對我來說,使用的Praetorian的例子更細化的版本爲我工作。 我定義了類似is_compat<T, Arg>
的東西,然後將其輸入std::enable_if<>
表達式(利用std::decay<>
來簡化匹配)。
編輯:發現std::is_convertible
,簡單得多。
自包含示例:
內嵌例子:
#include <type_traits>
// Syntactic sugar
using std::enable_if;
using std::is_convertible;
template<bool Expr, typename Result = void>
using enable_if_t = typename enable_if<Expr, Result>::type;
template<typename From, typename To>
using enable_if_convertible_t = enable_if_t<is_convertible<From, To>::value>;
然後,你可以做的過載,如:
template<typename ... Args>
void my_func(Args&& ... args) {
cout << "1. my_func<Args...>(" << name_trait_list<Args&&...>::join() << ")" << endl;
}
// Use template with enable_if to catch as many types as possible
template<typename T1,
typename = enable_if_convertible_t<T1, string>>
void my_func(int y, T1&& z) {
cout
<< "2. my_func<T1:string>(int, " << name_trait<decltype(z)>::name()
<< ")" << endl;
}
// Example using multiple types (let compiler handle the combinatorics)
template<typename T1, typename T2,
typename = enable_if_t<is_convertible<T1, string>::value &&
is_convertible<T2, double>::value>>
void my_func(int y, T1&& z, T2&& zz) {
cout
<< "3. my_func<T1:string, T2:double>(int, "
<< name_trait<decltype(z)>::name() << ", "
<< name_trait<decltype(zz)>::name() << ")" << endl;
}
(注:name_trait*
是一個家庭烘焙類)
輸出示例:
>>> (my_func(1, 2, 5, string("!!!")));
1. my_func<Args...>(int&&, int&&, int&&, std::string&&)
>>> (my_func(3, string("Hello")));
2. my_func<T1:string>(int, std::string&&)
>>> (my_func(4, (const string&)string("kinda")));
2. my_func<T1:string>(int, const std::string&)
>>> (my_func(5, "World"));
2. my_func<T1:string>(int, const char[6]&)
>>> (my_func(6, var));
2. my_func<T1:string>(int, char[6]&)
>>> (my_func(7, var, 12));
3. my_func<T1:string, T2:double>(int, char[6]&, int&&)
>>> (my_func(9, var, 12.0));
3. my_func<T1:string, T2:double>(int, char[6]&, double&&)
不應該是'is_related,Args >> ...'?另外,爲什麼它應該禁用,如果類型是相同的? –
0x499602D2
@ 0x499602D2不,'args'需要在'is_related'內擴展,因爲您希望在sizeof ...(Args)!= 1'時選擇主'is_related'模板。當類型相同時,您想禁用它,因爲在這種情況下,您希望選擇複製/移動構造函數而不是完美的轉發構造函數。 – Praetorian
哦,我沒有注意到主模板有模板包。無論如何,你是說如果一個'包裝器'包裝 w(x,y,z)'其中'{x,y,z}'都是類型'Obj'(意思是'int'),那麼構造器模板* shouldn不會被選中?我認爲你認爲他們不應該因爲你使用'DisableIf'。但我認爲它應該是'EnableIf'。 –
0x499602D2