C++如何区分容器模板和本机类型

Ste*_*ve 6 c++ templates

我有以下问题:

template<class T>
void set(std::string path, const T data)
{
   stringstream ss;
   ss << data << std::endl;
   write(path, ss.str();
}

template<class T>
void set(std::string path, const T data)
{
    std::stringstream ss;
    for(typename T::const_iterator it = data.begin(); it < data.end(); ++it)
    {
       ss << *it;
       if(it < data.end() -1 )
          ss << ", ";
    }
    ss << std::endl;
    write(path, ss.str());
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

error: ‘template<class T> void myclass::set(std::string, T)’ cannot be overloaded
error: with ‘template<class T> void myclass::set(std::string, T)’
Run Code Online (Sandbox Code Playgroud)

有没有办法区分容器类型和模板中的其他类型?

Ker*_* SB 8

使用特征:

#include <type_traits>

template <typename T>
typename std::enable_if<is_container<T>::value>::type
set (std::string const & path, T const & container)
{
    // for (auto const & x : container) // ...
}


template <typename T>
typename std::enable_if<!is_container<T>::value>::type
set (std::string const & path, T const & data)
{
    std::ostringstream oss;
    oss << data;
    write(path, oss.str());
}
Run Code Online (Sandbox Code Playgroud)

您可以在漂亮的打印机代码中找到合适的特性.


Fle*_*exo 6

在C++ 03中,您可以使用一点SFINAE来执行此操作,以选择性地为不同类型启用不同版本的函数:

#include <boost/type_traits.hpp>
#include <sstream>
#include <iostream>
#include <vector>

using namespace std;

template<class T>
void set(typename boost::enable_if<boost::is_pod<T>, std::string>::type path, const T data)
{
   std::cout << "POD" << std::endl;
   stringstream ss;
   ss << data << std::endl;
}

template<class T>
void set(typename boost::disable_if<boost::is_pod<T>, std::string>::type path, const T data)
{
    std::cout << "Non-POD" << std::endl;
    std::stringstream ss;
    for(typename T::const_iterator it = data.begin(); it < data.end(); ++it)
    {
       ss << *it;
       if(it < data.end() -1 )
          ss << ", ";
    }
    ss << std::endl;
}

int main() {
  int i;
  float f;
  std::vector<int> v;
  set("", v);
  set("", i);
  set("", f);
}
Run Code Online (Sandbox Code Playgroud)

我在这里使用了boost来方便,但如果不能选择boost或者使用C++ 11,你可以自己动手.

is_pod是不是很想要真正,你可能想的is_container特质,但,这不是那么微不足道,你需要让自己的特质,并is_pod使得如何使用特性来选择性地启用功能的简单回答一个很好的近似.