无法从字符串转换为模板 C2664

Cannot convert from string to template C2664

我创建了List(一个带有模板的class),它的构造函数接收到一个值T。我正在尝试在名为 Menu 的 class 的 switch 中设置该类型的值(也使用模板)。当我尝试 运行 Menu.run() 时,所有开关选项都有效,但字符串除外。

错误是

Error C2664 'List<T>::List(const List<T> &)': cannot convert argument 1 from 'const char [2]' to 'T'

//Class List

template <class T>
class List {
public:
List(T value) {
        this->head = nullptr;
        this->tail = nullptr;
        this->value = value;
        this->name = "no name";
    }
protected:
    List* head;
    List* tail;
    T value;
    std::string name;

};
//Class Menu
template<typename T>
class Menu{
public:
    Menu(int dataType) {
        this->dataType = dataType;
    }

    void run(){
        std::map<std::string, List< T > * > list;               
        List< T >* list1 = new List< T >("Test");
        std::cout << list1->toString() << std::endl;
    }
int main(){
    int dataType = 1;
    if (dataType == 1) {
        Menu <std::string> c(dataType);
        c.run();        
    }else if (dataType == 2) {
        Menu <int> c(dataType);
        c.run();
    }else if (dataType == 3) {
        Menu<double> c(dataType);
        c.run();
    }else if (dataType == 4) {
        Menu<char> c(dataType);
        c.run();
    }
    return 0;
}

在您的 main 函数中,编译器必须编译您的所有代码。即使它稍后会优化它,因为它可以看到 dataType == 1 c++ 标准说它必须首先为所有数据类型生成代码。

您可以使用 if constexpr 来解决这个问题,这样编译器只编译实际使用的代码:

int main(){
    const int dataType = 1;
    if constexpr (dataType == 1) {
        Menu <std::string> c(dataType);
        c.run();        
    }else if (dataType == 2) {
        Menu <int> c(dataType);
        c.run();
    }else if (dataType == 3) {
        Menu<double> c(dataType);
        c.run();
    }else if (dataType == 4) {
        Menu<char> c(dataType);
        c.run();
    }
    return 0;
}

听起来这并不是您真正想要的。正确的解决方案是修复导致失败的行:

List< T >* list1 = new List< T >("Test");

这仅在Tstd::string时有效。如果你用更通用的东西替换它,那么你的代码将编译。您可以使用默认构造值:

List< T >* list1 = new List< T >(T{});

或者更可能的是,您的作业要求您从控制台读取值:

T value;
while (!(std::cin >> value))
{
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    std::cout << "invalid value\n";
}
List< T >* list1 = new List< T >(value);