xmllmx
xmllmx

Reputation: 42379

Why does std::add_lvalue_reference not behave as expected?

#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
}

My compiler is clang 7.0, compiled with c++17. The error message is:

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

Why is f1 ok but f2 isn't?

Upvotes: 1

Views: 159

Answers (1)

songyuanyao
songyuanyao

Reputation: 173004

std::add_lvalue_reference_t<T> is defined as typename std::add_lvalue_reference<T>::type, then for template<typename T> void f2(Ref2<T>), i.e. template<typename T> void f2(typename std::add_lvalue_reference<T>::type), belongs to non-deduced context, which causes template argument deduction fails.

In the following cases, the types, templates, and non-type values that are used to compose P do not participate in template argument deduction, but instead use the template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.

1) The nested-name-specifier (everything to the left of the scope resolution operator ::) of a type that was specified using a qualified-id:

Upvotes: 2

Related Questions