Leszek Swirski
Leszek Swirski

Reputation: 51

VS2012 - Decltype as template parameter in trailing return type

The following code works on gcc and even VC11 Nov CTP, but fails to compile with 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 seems to fail a decltype is passed as a template parameter in a return value: it thinks "T=unknown". Note that f compiles fine,despite using decltype inside of it.

Is this a compiler bug in the RTM? And if so, is there a way of working around it?

Upvotes: 1

Views: 664

Answers (1)

Leszek Swirski
Leszek Swirski

Reputation: 51

I've found a workaround.

The trick is to pass the entire return type into a helper struct, and force the template to be resolved there. typedef-ing the return type in a helper struct doesn't seem to be enough, as the decltyped template parameters still appear to be unknown. However, setting it as the return type of a function in a helper struct seems to force the type to become resolved. Then, you can simply get the return type of this function (again using decltype).

Wrapping this up in a workaround macro gives

#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

Adding this to the above gives: http://rise4fun.com/Vcpp/JplI

Upvotes: 2

Related Questions