Как я могу использовать вложенный тип, принадлежащий шаблонному классу, в другой шаблонной функции в C ++? - PullRequest
4 голосов
/ 04 апреля 2019

Я устанавливаю функцию, которая инициализирует кортежи на основе типа кортежа и структуры функтора For, которая имеет аргумент шаблона size_t INDEX, чтобы сохранить индекс времени компиляции.Этот функтор также может зависеть от других аргументов шаблона T....Из-за этого функторы существуют в других структурах (TClass в этом примере), которые содержат эти аргументы шаблона.

Функция инициализации (называемая здесь Bar) имеет аргумент шаблона template<std::size_t> class, чтобы гарантировать, что используемый класс действительно может хранить индекс.

Хотя дизайн, который я придумал, работает нормально, когда я вызываю его из не шаблонной функции, он не компилируется, если шаблон T2 функции действительно определяет параметр шаблона оболочки TClass.

Вот определение функтора For, заключенного в TClass:

#include <cstdlib>

template <typename T> struct TClass {

    template<std::size_t INDEX> struct For {

        void operator()() {}
    };      
};

А вот вызовы функций, которые я хочу использовать:

template <template<std::size_t> class FOR> void bar() {
    //...
} 

template <typename T> void foo() {  
   bar<TClass<T>::For>(); //Does not compile
}

int main() {

    bar<TClass<int>::For>(); //Works
    foo<int>(); 

    return 0;
}

Вывод компилятора для ошибочного foo -call:

error: dependent-name ‘TClass<T>::For’ is parsed as a non-type, but instantiation yields a type
    Bar<TClass<T>::For>(); //Does not compile

Я знаю, что именам зависимых типов обычно должен предшествовать typename, но это также не обязательно дляпервый bar -звук.Я предположил, что это потому, что аргумент шаблона может быть интерпретирован только как тип.Поэтому я подумал, что, возможно, typename приведет к правильной компиляции, но если я изменю foo на

template <typename T> void foo() {  
   bar<typename TClass<T>::For>(); //Does not compile
}

, я получу:

error: ‘typename TClass<int>::For’ names ‘template<long unsigned int INDEX> struct TClass<int>::For’, which is not a type
    Bar<typename TClass<T>::For>(); //Does not compile

Я также придумалконструкция, в которой () -оператор TClass зависит от шаблона INDEX, который также отлично работает, потому что больше нет необходимости использовать вложенные типы.Это выглядит так:

#include <cstdlib>

template <typename T> struct TClass {

    template<std::size_t INDEX> void operator()() {}
};

template <typename FOR> void bar() {
    //...
} 

template <typename T> void foo() {  
   bar<TClass<T>>(); //Does compile
}

По-видимому, невозможно использовать имена зависимых типов в функциях, где шаблон типа определяется параметрами шаблона функции, но почему?И как мне правильно это реализовать?Чтобы упростить написание будущих проверок типов с помощью признаков типа, я бы предпочел использовать функтор.

1 Ответ

4 голосов
/ 04 апреля 2019

Компилятор не может знать, что TClass<T>::For ссылается на шаблон на первом этапе создания шаблона. Нужно немного помочь с ключевым словом template. Исправлено:

template <typename T> void foo() {  
    bar<TClass<T>::template For>(); 
}
...