Почему я получаю
Ошибка C2597: недопустимая ссылка на нестатический элемент
'derived<<unnamed-symbol>>::T'
когда я пытаюсь скомпилировать этот код в Visual C ++ 2010 x64? (Кажется, хорошо на x86 … какой из них правильный?)
struct base { typedef int T; };
template<class>
struct derived : base
{
using base::T;
derived(T = T()) { }
};
int main()
{
derived<int>();
return 0;
}
Как отмечается в комментарии Преториана, проблема заключается в T()
значение по умолчанию. Основываясь на деталях ошибки, using base::T
видимо смущает компилятор в поиске T()
как вызов нестатической функции-члена base
а не конструкция экземпляра типа T
,
Вот интересное исправление, которое работает в MSVC 2005 x86 (я не пробовал никакой другой компилятор). Обратите внимание, что T()
сохраняется Это либо однозначно using base::T
или просто силы T
ссылаться на унаследованный тип, а не на using
один (который, очевидно, не то же самое для компилятора).
//...
template<class>
struct derived : base
{
using base::T;
derived(T = static_cast<T>( T() )) { } //No error
};
//...
Редактировать: Попробуйте изменить base
на это и посмотрите, какие сообщения об ошибках вы получаете:
struct base { struct T{T(){}}; };
Я получаю оригинал C2597
, но также это:
ошибка C2440: ‘аргумент по умолчанию’: невозможно преобразовать из » в ‘base :: T’
Ни один конструктор не может принять тип источника, или разрешение перегрузки конструктора было неоднозначным
Я не знаю, что означает компилятор ''
там, но это, вероятно, аналогичная проблема с оригинальным определением base
, Это компилируется нормально, если я удаляю using base::T;
линия.
Почему вы используете using base::T
? Типы, определенные в базовом классе, будут автоматически доступны в производном классе.
struct base { typedef int T; };
template< class X >
struct derived : base {};
derived<int>::T v = 0; // this is OK in C++
Используйте это вместо этого (должно быть понятно):
template<class T>
struct derived : base
{
derived(T = T()) { }
};