const T& amp的专用模板适用于大型和T型适用于简单类型

时间:2017-01-05 10:44:10

标签: c++ c++11 templates template-specialization

我需要做这个魔术:

我有一个模板:

template <class T>
void Foo(const T& value)

但我需要将它专门用于简单类型,例如boolint等,所以它将通过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
}

但它无法编译。

如何正确地做到这一点?

5 个答案:

答案 0 :(得分:5)

如果所有基本类型和指针的功能相同,我猜您可以使用std::is_fundamentalstd::is_pointerstd::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;
}

wandbox

上的示例

答案 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;
}

see the code here

答案 4 :(得分:1)

也许这会有所帮助:

template<typename T>
void foo(conditional_t<is_fundamental_v<T> || is_pointer_v<T>, const T, const T&> x)
{
    //do stuff
}