我需要做这个魔术:
我有一个模板:
template <class T>
void Foo(const T& value)
但我需要将它专门用于简单类型,例如bool
,int
等,所以它将通过const值传递,而不是通过const引用传递:
template <>
void Foo<bool>(const bool value)
template <>
void Foo<int>(const int value)
// and so on, including std::nullptr_t
template <>
void Foo<std::nullptr_t>(std::nullptr_t)
{
// some special behavior
}
但它无法编译。
如何正确地做到这一点?
答案 0 :(得分:5)
如果所有基本类型和指针的功能相同,我猜您可以使用std::is_fundamental,std::is_pointer和std::enable_if:
template<typename T>
std::enable_if_t<std::is_fundamental<T>::value || std::is_pointer<T>::value>
foo(const T) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
template<typename T>
std::enable_if_t<!std::is_fundamental<T>::value && !std::is_pointer<T>::value>
foo(const T&) {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
上的示例
答案 1 :(得分:2)
您还可以使用标记式调度和完美转发....
template<typename T>
void Foo_dispatch(T val, std::true_type){
std::cout << val << " Passed by value\n";
}
template<typename T>
void Foo_dispatch(const T& val, std::false_type){
std::cout << val << " Passed by reference\n";
}
void Foo(std::nullptr_t){}
template <class T>
void Foo(T&& value){
using type = std::integral_constant<bool, std::is_fundamental<T>::value || std::is_pointer<T>::value>;
Foo_dispatch(std::forward<T>(value), type());
}
示例用法:
int main(){
Foo(23);
Foo(45.343);
Foo("Hahah");
Foo(std::string("Cool stuff"));
Foo(nullptr);
Foo(&"huhu");
}
产地:
23 Passed by value
45.343 Passed by value
Hahah Passed by reference
Cool stuff Passed by reference
nullptr_t gotten
0x400e52 Passed by value
见Live
答案 2 :(得分:1)
这是因为
void Foo<bool>(const bool value)
不是的专业化
但它是重载(函数与类模板不同,因为函数可能会重载)。 你可以做的是例如: (或者只使用简单的非模板化重载,因为它们优先于模板实例化)template <class T>
void Foo(const T& value)
template <class T>
struct Foo {
void operator ()(const T& value);
};
template <>
struct Foo<bool> {
void operator ()(bool value);
};
// ... other specializations
答案 3 :(得分:1)
你可以这样做:
template <class T>
void Foo(const T& value)
{
return ;
}
void Foo(const bool value)
{ }
void Foo(const int value)
{ }
// and so on, including std::nullptr_t
void Foo(std::nullptr_t)
{
// some special behavior
}
int main( ) {
Foo(1);
Foo(true);
Foo(nullptr);
return 0;
}
答案 4 :(得分:1)
也许这会有所帮助:
template<typename T>
void foo(conditional_t<is_fundamental_v<T> || is_pointer_v<T>, const T, const T&> x)
{
//do stuff
}