模板别名如何影响模板参数推导?

HC4*_*ica 12 c++ templates c++11 template-aliases

在C++ 03中,模板参数推导在某些上下文中不会发生.例如:

template <typename T> struct B {};

template <typename T>
struct A
{
    typedef B<T> type;
};

template <typename T>
void f(typename A<T>::type);

int main()
{
    B<int> b;
    f(b);  // ERROR: no match
}
Run Code Online (Sandbox Code Playgroud)

这里int不推断T,因为嵌套类型A<T>::type是非推断的上下文.

我是否写过这样的函数:

template <typename T> struct B {};

template <typename T>
void f(B<T>);

int main()
{
    B<int> b;
    f(b);
}
Run Code Online (Sandbox Code Playgroud)

一切都很好,因为B<T> 推断的背景.

但是,在C++ 11中,模板别名可用于以类似于第二个示例的语法伪装嵌套类型.例如:

template <typename T> struct B {};

template <typename T>
struct A
{
    typedef B<T> type;
};

template <typename T>
using C = typename A<T>::type;

template <typename T>
void f(C<T>);

int main()
{
    B<int> b;
    f(b);
}
Run Code Online (Sandbox Code Playgroud)

模板参数推导会在这种情况下起作用吗?换句话说,模板别名是推导上下文还是非推导上下文?或者他们是否继承了别名的推导/非推断状态?

Joh*_*itb 9

换句话说,模板别名是推导上下文还是非推导上下文?

它们与等效代码一样可以在不使用模板别名的情况下进行推导.例如

template<typename T>
using ref = T&;

template<typename T>
void f(ref<T> r);
Run Code Online (Sandbox Code Playgroud)

现在你可以打电话f(x),T并将被推断完美.在f已经定义的时候,ref<T>被类型取代T&.并且T&是推断的背景.

在您的情况下C<T>被替换为typename A<T>::type,并且这是一个非推断的上下文T,因此T无法推断.

  • Johannes 的优秀回答中的关键短语是“已经在‘f’的*定义时间*”(重点是我的)。很容易错过这一点,但知道它可以解释一切。 (2认同)