C ++ перечисление и шаблоны - PullRequest
0 голосов
/ 07 июня 2010

Я получаю следующую ошибку с VS2008: преобразование в тип перечисления требует явного приведения (static_cast, C-style или функционального стиля)

При приведении к понижению класса ClassA к ClassA_1 и ClassA_1 является шаблонным классом, который получил перечисление для параметра, такого как:

ЭТО РЕДАКТИРОВАТЬ МОЙ ВОПРОС, КОТОРЫЙ ПОВТОРНО ИСПОЛЬЗУЙТЕ ОТВЕТ НИЖЕ, НО МОДИФИЦИРОВАННЫЙ, ЧТОБЫ ПРИЧИНИТЬ ПРОБЛЕМУ, КОТОРУЮ Я ИМЕЕТ, вот и мы:

Хорошо, я смог воспроизвести мою ошибку с помощью этого кода:

class ClassA
{
public:
    virtual ~ClassA(){}
};

template <class Param1 = void*> class ClassB : public ClassA {
public:
    //constructor
    ClassB(Param1 p1 = NULL)
    {
        _p1 = p1;
    }
    //ClassB(const ClassB<Param1>& ref);
    Param1 _p1;
    ~ClassB(){}
};

enum lolcakes {
    cakeisalie,
};


ClassA* ptr = new ClassB<lolcakes>(lolcakes::cakeisalie);

ClassB<lolcakes>* a1 = (ClassB<lolcakes>*)ptr;

Ответы [ 2 ]

2 голосов
/ 07 июня 2010

Здесь так много синтаксических ошибок, что я не знаю, с чего начать. В следующий раз, пожалуйста, отправьте фактический код, который вы использовали.

Для начала, я предполагаю, что вы хотели написать это:

ClassA<myenum>* a = new ClassA_1<myenum>();

Другими словами, a - это указатель , а его тип - ClassA<myenum>*, а не просто ClassA (и мы проигнорируем отсутствующий аргумент для конструктора).

Теперь ваш синтаксис приведения неверен в обоих случаях. Круглые скобки должны идти только вокруг типа . Но все равно лучше использовать static_cast:

ClassA_1<myenum>* a1 = static_cast<ClassA_1<myenum>*>(a);

Это работает.

ОБНОВЛЕНИЕ После редактирования вопроса:

Важная ошибка в этой строке:

ClassB(Param1 p1 = NULL)

вы не можете использовать NULL в качестве параметра по умолчанию, поскольку ваш тип Param1 является , а не указателем - это перечисление (строго говоря, это должно работать, поскольку NULL определяется как равное 0 в C ++, но, тем не менее, это логическая ошибка). Вместо того, чтобы делать параметр необязательным, лучшей альтернативой будет перегружать конструктор. В качестве альтернативы также работает следующее:

ClassB(Param1 p1 = Param1())

Используется значение по умолчанию для типа Param1.

В коде есть дополнительная ошибка:

ClassA* ptr = new ClassB<lolcakes>(lolcakes::cakeisalie);

Константы перечисления не работают так в C ++: они не создают собственное пространство имен, поэтому их использование не может быть квалифицированным. Вместо этого опустите имя перечисления:

ClassA* ptr = new ClassB<lolcakes>(cakeisalie);

Наконец, пожалуйста, не используйте приведения в стиле C, ever . Всегда заменяйте их соответствующими приведениями в стиле C ++. В вашем случае замените

ClassB<lolcakes>* a1 = (ClassB<lolcakes>*)ptr;

с

ClassB<lolcakes>* a1 = boost::polymorphic_downcast<ClassB<lolcakes>*>(ptr);
// or
ClassB<lolcakes>* a1 = static_cast<ClassB<lolcakes>*>(ptr);
1 голос
/ 07 июня 2010
class ClassA
{
    virtual ~ClassA(){}
};

template <class Param1> class ClassB : public ClassA {
public:
    //constructor
    ClassB(Param1 p1)
        : _p1(p1) {}
    ClassB(const ClassB<Param1>& ref);
    Param1 _p1;
    ~ClassB(){}
};

enum lolcakes {
    cakeisalie,
};

ClassA* ptr = new ClassB<lolcakes>(lolcakes::cakeisalie);
ClassB<lolcakes> a = (ClassB<lolcakes>(lolcakes::cakeisalie));
ClassB<lolcakes> a1 = a;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...