我怎么知道C++模板是容器还是类型?

fee*_*ree 7 c++ templates stl

我给出以下代码来表明我的问题:

template<T>
void my_fun(T &obj)
{
  if(obj is a type like float, std::string, double)
   {
       perform1()
  }
  if(obj is a container like std::vector, std::list)
  {
      perform2()
 } 
}
std::vector<int> abc;
my_fun(abc);
int d;
my_fun(d);
Run Code Online (Sandbox Code Playgroud)

然后我的问题,我怎么知道模板是指简单类型还是容器?谢谢.

vso*_*tco 5

您可以编写自己的特征,enable_if并通过带有多个重载的表达式SFINAE在其上。这是使用技巧的解决方案(大概会在C ++ 17中出现):void_t

#include <iostream>
#include <type_traits>
#include <vector>

template<typename ...>
using to_void = void; // maps everything to void, used in non-evaluated contexts

template<typename T, typename = void>
struct is_container : std::false_type
{};

template<typename T>
struct is_container<T,
        to_void<decltype(std::declval<T>().begin()),
                decltype(std::declval<T>().end()),
                typename T::value_type
        >> : std::true_type // will  be enabled for iterable objects
{};

template<typename T>
void f(T param, typename std::enable_if<is_container<T>::value>::type* = nullptr)
{
    std::cout << "Container\n";
}

template<typename T>
void f(T param, typename std::enable_if<std::is_fundamental<T>::value>::type* = nullptr)
{
    std::cout << "Fundamental\n";
}

template<typename T>
void f(T param, 
    typename std::enable_if<!std::is_fundamental<T>::value>::type* = nullptr, 
    typename std::enable_if<!is_container<T>::value>::type* = nullptr)
{
    std::cout << "Other\n";
}

struct Foo{};

int main()
{
    int x{};            // fundamental
    std::vector<int> v; // container
    Foo s{};    // other

    f(x);
    f(v);
    f(s);
}
Run Code Online (Sandbox Code Playgroud)

Live on Coliru


Lou*_*uen 2

您有多种选择可供选择。

  • 如果您想要默认行为,并且仅更改一种类型(或几种),请为您的函数使用模板专门化

例如 :

template<typename T>
void myfunc() { /*default*/ }


template<>
void myfunc<int>() { /*specialized version for int */}
Run Code Online (Sandbox Code Playgroud)
  • 如果您想更改通用类型组的函数行为,可以使用类型特征(类似于std::is_fundamental)。在这种情况下,您可能必须实现自己的类型特征。