Невозможно преобразовать из строки в шаблон C2664 - PullRequest
0 голосов
/ 17 июня 2020

Я создал List (класс с шаблоном), его конструктор получает значение T. Я пытаюсь установить этот тип значения в switch класса с именем Menu (также с шаблонами). Когда я пытался запустить Menu.run(), все параметры переключателя работали, кроме строки.

Ошибка:

Ошибка C2664 'List :: List (const List &)': невозможно преобразовать аргумент 1 из 'const char [2]' в '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;
}

1 Ответ

0 голосов
/ 17 июня 2020

В вашей функции 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");

Это действительно только тогда, когда T равно std::string. Если вы замените его чем-то более общим c, ваш код будет скомпилирован. Вы можете использовать сконструированное значение по умолчанию:

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);
...