VS2012-在尾部返回类型中将类型声明为模板参数

VS2012 - Decltype as template parameter in trailing return type

本文关键字:声明 参数 类型 尾部 返回类型 VS2012-      更新时间:2023-10-16

以下代码适用于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:http://rise4fun.com/Vcpp/9u2
  • VC11 CTP:http://rise4fun.com/Vcpp/6lS

VC11RTM似乎失败了——decltype作为模板参数在返回值中传递:它认为"T=unknown"。注意,尽管f内部使用了decltype,但它编译得很好

这是RTM中的编译器错误吗?如果是这样,有没有办法解决这个问题?

我找到了一个解决方法。

诀窍是将整个返回类型传递到辅助结构中,并强制在那里解析模板。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