为什么std :: add_lvalue_reference的行为不符合预期?

时间:2018-12-08 02:42:01

标签: c++ c++11 standards typetraits using-declaration

#include <type_traits>

template<typename T>
using Ref1 = T & ;

template<typename T>
using Ref2 = std::add_lvalue_reference_t<T>;

template<typename T>
void f1(Ref1<T>)
{}

template<typename T>
void f2(Ref2<T>)
{}

int main()
{
    int n{};
    f1(n); // ok
    f2(n); // error
}

我的编译器是clang 7.0,使用c++17编译。错误消息是:

error : no matching function for call to 'f2'
  note: candidate template ignored:
        couldn't infer template argument 'T'

为什么f1没问题,但是f2不好?

1 个答案:

答案 0 :(得分:2)

std::add_lvalue_reference_t<T>被定义为typename std::add_lvalue_reference<T>::type,然后对于template<typename T> void f2(Ref2<T>),即template<typename T> void f2(typename std::add_lvalue_reference<T>::type)属于non-deduced context,这导致模板参数推导失败。

  

在以下情况下,用于构成P的类型,模板和非类型值不参与模板自变量的推导,而是使用在其他地方推导或明确指定的模板自变量。如果仅在非推导上下文中使用模板参数且未明确指定模板参数,则模板参数推导将失败。

     

1)嵌套名称说明符(范围解析运算符::的所有内容),该类型是使用限定ID指定的: