use*_*952 4 c++ templates c++11
我有一个模板包装函数,它返回一个这样的值:
template<class T>
T foo(Bar& bar, const char* key) {
return bar.value<T>(key);
}
Run Code Online (Sandbox Code Playgroud)
但我希望它处理指针类型有点不同,像这样:
template<class T>
T foo(Bar& bar, const char* key) {
return (T)bar.value<void*>(key);
}
Run Code Online (Sandbox Code Playgroud)
所以我可以这样做:
int x = foo<int>(bar, "x");
Baz* b = foo<Baz*>(bar, "b");
Run Code Online (Sandbox Code Playgroud)
像上面那样写它显然会因为多个定义而给我一个错误.有没有其他方法可以做到这一点?我宁愿不为每个使用指针的函数添加一个强制转换.
我尝试过以下方法:
template<class T>
T foo(Bar& bar, const char* key) {
if(std::is_pointer<T>::value)
return (T)bar.value<void*>(key);
else
return bar.value<T>(key);
}
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为涉及QVariants并且它们通过仅使用未知指针类型(the bar.value<T>)实例化其模板函数之一而产生错误.
Pra*_*ian 12
使用标记分派将调用委托给辅助函数,这些函数根据是否T为指针类型执行不同的操作.
namespace detail
{
template<class T>
T foo(Bar& bar, const char* key, std::false_type /*not is_pointer*/) {
return bar.value<T>(key);
}
template<class T>
T foo(Bar& bar, const char* key, std::true_type /*is_pointer*/) {
return (T)bar.value<void*>(key);
}
}
template<class T>
T foo(Bar& bar, const char* key) {
return detail::foo<T>(bar, key, std::is_pointer<T>{});
}
Run Code Online (Sandbox Code Playgroud)
函数的部分特化不是语言的一部分.
你可以举个例子:
使用SFINAE.
template<class T>
typename std::enable_if<std::is_pointer<T>::value, T>::type
foo(Bar& bar, const char* key) {return (T)bar.value<void*>(key);}
template<class T>
typename std::enable_if<!std::is_pointer<T>::value, T>::type
foo(Bar& bar, const char* key) {return bar.value<T>(key);}
Run Code Online (Sandbox Code Playgroud)