如何编写模板功能接受&&和const&都?

时间:2014-10-03 13:19:21

标签: c++ templates c++11 move-semantics

例如

template<typename T> void f(T&& t) {}
template<typename T> void f(T const& t) {}

当我打电话

int i;
f(i); // call f(T&&) which I expect to call f(T const&), how to solve it?
f(10); // call f(T&&), that is fine

2 个答案:

答案 0 :(得分:7)

这是一种方式:

#include <type_traits>

template<typename T>
typename std::enable_if< !std::is_lvalue_reference<T>::value >::type
f(T&& t) {}

template<typename T> void f(T const& t) {}

另一种可能性是标签调度:

template<typename T>
void f_(const T&, std::true_type) { std::cout << "const T&\n"; }
template<typename T>
void f_(T&&, std::false_type) { std::cout << "T&&\n"; }

template<typename T>
void f(T&& t)
{
    f_(std::forward<T>(t), std::is_lvalue_reference<T>{} );
}

答案 1 :(得分:4)

另一种选择是:

template<typename T>
struct f_caller
{
    void operator () (T&& ) { std::cout << "T&&" << std::endl; }
    void operator () (T const& ) { std::cout << "const T&" << std::endl; }
};


template <typename T>
void f(T&& t)
{
    f_caller<typename std::decay<T>::type>()(std::forward<T>(t));
}

Live example