2014-10-03 46 views
3

例如如何寫一個模板函數接受&&和const&兩者?

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 
+0

是您要重載函數R值和L值和類型來區分,也模板? – Niall 2014-10-03 13:21:31

+0

你想要rvalues去'T &&'重載和左值去'T const&'重載嗎? – 2014-10-03 13:25:10

+0

可能相關:http://stackoverflow.com/q/25938749/3549027 – dlf 2014-10-03 13:25:23

回答

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

+1也可以使用'std :: is_rvalue_reference :: value' – P0W 2014-10-03 13:33:04

+2

@ P0W這也是我的想法,但[nope](http://coliru.stacked-crooked.com/a/c3c3048525a93b69)。 – jrok 2014-10-03 13:34:48

+0

啊現在我意識到看到'std :: is_rvalue_reference'的可能實現# – P0W 2014-10-03 13:38:07

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

相關問題