Подтвердить что ты не робот

Почему компилятор пытается создать экземпляр шаблона, который я фактически не создаю где-либо?

Обновлено ниже.
Ниже приведен весь код, который у меня есть на моем main.cpp:

template<class T>
struct other_traits;

template<class T>
struct some_traits{
    typedef decltype(&T::operator()) Fty;
    typedef typename other_traits<Fty>::type type;
};

int main(){
}

Но я получаю следующие ошибки в Visual Studio 2010, а g++ компилируется просто отлично:

src\main.cpp(9): ошибка C2146: синтаксическая ошибка: отсутствует ';' перед идентификатором 'type'
--src\main.cpp(10): см. ссылку на экземпляр шаблона шаблона 'some_traits<T>', скомпилированный
src\main.cpp(9): ошибка C2868: 'some_traits<T>::type': незаконный синтаксис для использования-объявления; ожидаемое квалифицированное имя

(Мне нравится этот последний, общий wtf.)

Можно ли считать это ошибкой в ​​VC10 или есть ли веская причина для раннего создания экземпляра? Или это ошибка с decltype, которая заставляет компилятор думать, что Fty не является зависимым именем?


Обновление. Я пытался обмануть компилятор, думая, что Fty является зависимым именем, использующим базовый класс для наследования:

template<class T>
struct other_traits;

template<class R, class C>
struct other_traits<R (C::*)()>{
    typedef R type;
};

template<class Fty>
struct base_traits{
    typedef typename other_traits<Fty>::type type;
};

template<class T>
struct some_traits
    : public base_traits<decltype(&T::operator())>
{};

Но компилятор все равно пытается создать/скомпилировать все на месте, извергая эти ошибки:

src\main.cpp(13): error C2039: 'type' : is not a member of 'other_traits<T>'
          with
          [
              T=
          ]
          src\main.cpp(19) : see reference to class template instantiation 'base_traits<Fty>' being compiled
          with
          [
              Fty=
          ]
          src\main.cpp(19) : see reference to class template instantiation 'some_traits<T>' being compiled
src\main.cpp(13): error C2146: syntax error : missing ';' before identifier 'type'
src\main.cpp(13): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
src\main.cpp(13): error C2602: 'base_traits<Fty>::type' is not a member of a base class of 'base_traits<Fty>'
          with
          [
              Fty=
          ]
          src\main.cpp(13) : see declaration of 'base_traits<Fty>::type'
          with
          [
              Fty=
          ]
src\main.cpp(13): error C2868: 'base_traits<Fty>::type' : illegal syntax for using-declaration; expected qualified-name
          with
          [
              Fty=
          ]

Обратите внимание, что параметры шаблона пусто. Любые идеи?

4b9b3361

Ответ 1

Кажется, это Ошибка (если не установлен специальный флаг, как указано ниже). Ниже приведен фрагмент веб-сайта Oracle для шаблонов С++:

7.2.2

Стандарт ISO С++ разрешает разработчикам писать классы шаблонов для которых все члены не могут быть юридический с заданным шаблоном аргумент. Пока незаконный члены не создаются, программа все еще хорошо сформирована. ИСО Стандартная библиотека С++ использует это техника. Однако Опция -template = wholeclass запускает все элементы и, следовательно, не может использоваться с таким шаблоном классов при создании экземпляров с помощью проблемные аргументы шаблона.

Ответ 2

Я думаю, вы наткнулись на ошибку, связанную с преждевременным экземпляром, когда компилятор видит decltype

Ответ 3

template<class T>
struct other_traits; // <-- I don't see a "type" attribute in this struct

template<class T>
struct some_traits{
    typedef decltype(&T::operator()) Fty;
    typedef typename other_traits<Fty>::type type; // <-- Here you are trying to access other_traits<T>::type which doesn't exist
};

int main(){
}

Ответ 4

Вы делаете одно предположение здесь, что технически неверно. пусть сначала займется этим.

Вы предполагаете, что синтаксическая ошибка означает, что шаблон создается. Это не то, как скомпилировать шаблоны . Сначала шаблон компилируется перед созданием экземпляра. Это фаза, в которой ищутся не зависящие имена. Синтаксические ошибки, безусловно, могут быть найдены на этом этапе. Например, все, что обязательно должно быть объявлено независимо от аргументов шаблона, должно заканчиваться на ;.

Теперь правильный вопрос заключается в правильности компилятора при рассмотрении специализаций other_traits<T>. Конечно, нет никакой специализации по линии 9, хотя позже могут быть специализации. Но будет ли это подходящей точкой для их создания? Мне пришлось бы посмотреть это (извините, AFS Away From Standardother_traits <T> будет линией 9, тогда нет специализаций, а other_traits<Fty>::type является недопустимым.Если точка инстанцирования для other_traits<Fty>::type будет такой же, как точка инстанцирования для some_traits<T>, т.е. нет, то other_traits<Fty>::type следует принять в фазе 1.