Задержка создания экземпляра функции-члена в базовом классе crtp

В настоящее время у меня есть базовый класс CRTP, который использует класс признаков для определения возвращаемого типа его функций-членов. Я играл с С++ 11 и получил следующий код, который устраняет необходимость в классе признаков, но требует параметров шаблона функции по умолчанию. Есть ли способ изменить это для работы в Visual Studio 2012, которая не поддерживает эту функцию С++ 11?

#include <iostream>

using namespace std;

template<typename T, typename Ignore> 
struct ignore { typedef T type; };

template<typename T> 
struct A 
{
    template<class IgnoredParam = void>
    auto foo() -> decltype(declval<typename ignore<T*, IgnoredParam>::type >()->foo_impl()) 
    {
        return static_cast<T*>(this)->foo_impl();
    }        
};

struct B : public A<B> 
{
    int foo_impl() { return 0;}

};

int main()
{
    B b;
    int i = b.foo();
    cout << i << '\n';
}

person Joe    schedule 10.06.2012    source источник
comment
Поддерживает ли он переменные параметры шаблона?   -  person Johannes Schaub - litb    schedule 10.06.2012
comment
@litb: Нет, он также не поддерживает шаблоны с переменным числом аргументов. вот список функций, которые он поддерживает.   -  person Joe    schedule 10.06.2012


Ответы (1)


Вы можете просто использовать

decltype(declval<T>()->foo_impl())

как тип отложенного возврата.

person Puppy    schedule 10.06.2012
comment
Когда я пытаюсь это сделать, я получаю сообщение об ошибке о недопустимом использовании неполного типа B. Я изменил объявление на auto foo() -> decltype(declval<T*>()->foo_impl()). Это то, что вы имели в виду? - person Joe; 10.06.2012
comment
@Joe: Какую версию VC11 вы используете? Насколько я знаю, то, что вы видите, является ошибкой и было исправлено после предварительного просмотра для разработчиков. - person ildjarn; 10.06.2012
comment
@ildjam: я получаю сообщение об ошибке, используя RC. Я также попробовал gcc 4.7 и получил ту же ошибку. Я думаю, что ошибка правильная, потому что компилятор пытается создать экземпляр foo, когда B все еще является неполным типом. Это то, что я пытался обойти с помощью ignore и параметра шаблона функции в моем исходном посте, который откладывал создание экземпляра до тех пор, пока foo не был фактически вызван, и в этот момент B был полным типом. - person Joe; 10.06.2012
comment
Нет, он не может использовать это, потому что функция объявляется сразу после создания экземпляра класса. Но T является неполным типом, когда создается экземпляр этого базового класса, что приведет к ошибке. - person Johannes Schaub - litb; 10.06.2012