模板参数和它自己的模板参数都包含同名的类型;如何在函数签名中引用第二个?

时间:2014-10-24 12:57:25

标签: c++ templates visual-studio-2012 visual-studio-2013 compiler-bug

考虑以下代码:

template<typename T>
struct Foo
{
    typedef T t_type;
};

template<typename T>
struct Bar
{
    typedef T t_type; 
};

template<typename U>
auto f() -> typename U::t_type::t_type
{
    return typename U::t_type::t_type();
}

int main(int, char**)
{
    typedef Foo<Bar<int>> Baz;
    f<Baz>();
}

它不能在VS2012下编译:

  

'U :: t_type :: {ctor} f(void)'的显式模板参数无效

似乎,编译器得出的结论是t_type中的第二个typename U::t_type::t_type正在命名一个构造函数而不是一个同名的嵌套类型。我有什么办法可以帮助澄清情况吗?

2 个答案:

答案 0 :(得分:1)

我认为这不会在2012年得到支持,但是:

template<class T>
using t_type=typename T::t_type;

template<typename U>
t_type<t_type<U>> f() {
  return {};
}

2012年,我们可以试试这个:

template<class T, size_t recurse>
struct r_type:
  r_type<typename T::t_type, recurse-1>
{};
template<class T>
struct r_type<T, 0> {
  typedef typename T::t_type t_type;
};

...

template<typename U>
auto f() -> typename r_type<U,1>::t_type {
  return {};
}

其中r_type代表&#34;递归类型&#34;。

答案 1 :(得分:1)

首先,您错过了typename关键字

template<typename U>
auto f() -> typename U::t_type::t_type
{
    return typename U::t_type::t_type();
}

和main应该有参数(int,char**)

那说..

has already been reported and apparently fixed [将会/已经] 在未指定的&#34; 未来版本&#34;)中发货。 MSVC 2013更新4也受到影响。

建议的解决方法是:

template<typename T>
struct Foo
{
    typedef T t_type;
};

template<typename T>
struct Bar
{
    typedef T t_type;
};

template<typename U>
auto f() -> typename U::t_type::template t_type
                                ^^^^^^^^
{
    return typename U::t_type::t_type();
}

int main(int, char**)
{
    typedef Foo<Bar<int>> Baz;
    f<Baz>();
}

虽然如果你使用上面的代码,一切都会如下图所示:

enter image description here