VS2012 - Decltype как параметр шаблона в возвращаемом типе

Следующий код работает на gcc и даже на VC11 Nov CTP, но не компилируется с VC11 RTM.

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 = unknown». Обратите внимание, что f компилируется нормально, несмотря на использование внутри него decltype.

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


person Leszek Swirski    schedule 17.04.2013    source источник


Ответы (1)


Я нашел обходной путь.

Хитрость заключается в том, чтобы передать весь возвращаемый тип во вспомогательную структуру и принудительно разрешить шаблон там. typedef-ing тип возвращаемого значения во вспомогательной структуре кажется недостаточным, поскольку параметры шаблона 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

person Leszek Swirski    schedule 17.04.2013