2013-04-17 4 views
1

Следующий код работает на gcc и даже VC11 Nov CTP, но не скомпилирован с RTM VC11.VS2012 - Decltype в качестве параметра шаблона в возвращаемом типе возврата

template<typename T> 
struct A { 
    typedef typename T::Type BreakMe; 
    T x; 
}; 
struct B { typedef int Type; }; 

template<typename T> 
struct C { 
    static A<T> f(A<T> a) { 
     return A<decltype(a.x)>(); 
    } 
    static auto g(A<T> a) -> A<decltype(a.x)> { 
     return A<decltype(a.x)>(); 
    } 
}; 

int main(int argc, char* argv[]) 
{ 
    C<B>::f(A<B>()); 
    C<B>::g(A<B>()); 
    return 0; 
} 

VC11 RTM кажется провалить decltype передается в качестве параметра шаблона в качестве возвращаемого значения: он считает, что «T = неизвестно ». Обратите внимание, что f компилируется отлично, несмотря на то, что внутри него используется decltype.

Является ли это ошибкой компилятора в RTM? И если да, есть ли способ обойти это?

ответ

2

Я нашел обходное решение.

Хитрость состоит в том, чтобы передать весь возвращаемый тип в вспомогательную структуру и заставить шаблон быть разрешенным там. typedef - тип возвращаемого значения в вспомогательной структуре не представляется достаточным, так как параметры шаблона decltyped остаются неизвестными. Однако установка его как возвращаемого типа функции в вспомогательной структуре, похоже, заставляет тип быть разрешенным. Затем вы можете просто получить возвращаемый тип этой функции (снова используя decltype).

Обертывание это вверх в обходной макрос дает

#if defined(_MSC_VER) && _MSC_VER <= 1700 
namespace workarounds { 
    template<typename T> 
    struct resolve_template { 
    static T ret(); 
    }; 
} 
#define RESOLVE_TEMPLATE(A) decltype(::workarounds::resolve_template<A>::ret()) 
#else 
#define RESOLVE_TEMPLATE(A) A 
#endif 

Добавление этого к вышесказанному дает: http://rise4fun.com/Vcpp/JplI

Смежные вопросы