c++ - 错误 C2893 : Failed to specialize function template C++

标签 c++ string split tokenize

我尝试创建如下所示的字符串拆分模板,但出现错误。

struct splitX
{
  enum empties_t { empties_ok, no_empties };
};

template <typename Container>
Container& split(
  Container&                                 result,
  const typename Container::value_type&      s,
  typename Container::value_type::value_type delimiter,
  splitX::empties_t                           empties = splitX::empties_ok )
{
  result.clear();
  std::istringstream ss( s );
  while (!ss.eof())
  {
      typename Container::value_type field;
      getline( ss, field, delimiter );
      if ((empties == split::no_empties) && field.empty()) continue;
      result.push_back( field );
  }
  return result;
}

当我尝试将它与如下 vector 类一起使用时,由于标题错误而失败:

std::getline(myfile,line);
std::vector<std::string> fields;
split(fields,line,' ');

// Test split function
std::cout << line << std::endl;
for(int i = 0; i < fields.size();i++)
  std::cout << fields[i];

最佳答案

好的,Microsoft Visual C++ 2008 不喜欢您的 Container::value_type::value_type

你可以使用这个可怕的结构:

template <typename T>
struct vte /*value_type_extractor*/
{
    typedef typename T::value_type type;
};

template <typename Container>
Container& split(
   Container&                                 result,
   const typename Container::value_type&      s,
   typename vte<typename vte<Container>::type>::type delimiter,
   splitX::empties_t                           empties = splitX::empties_ok )
{
  typedef typename Container::value_type string_type;
  typedef typename string_type::value_type elem_type;
  std::basic_istringstream<elem_type> ss( s );
  ...
}

或者,您可以使用 STL 样式:

#inlcude <iterator>

template <typename OutputIterator, typename StringType>
OutputIterator split(
  OutputIterator                  out,
  const StringType&               s,
  typename StringType::value_type delimiter,
  splitX::empties_t               empties = splitX::empties_ok )
{
  typedef typename StringType::value_type elem_type;
  std::basic_istringstream<elem_type> ss( s );
  while (!ss.eof())
  {
      StringType field;
      std::getline( ss, field, delimiter );
      if ((empties == splitX::no_empties) && field.empty()) continue;
      *out++ = field;
  }
  return out;
}

//somewhere in code
{
    ...
    split(std::back_inserter(your_container), line, ' ');
}

或者,你可以别装模版大神了,写两个重载函数:

template <typename Container>
Container& split(
   Container&              result,
   const std::string&      s,
   char                    delimiter,
   splitX::empties_t       empties = splitX::empties_ok )
{
  std::istringstream ss(s);
  ...
}

template <typename Container>
Container& split(
   Container&              result,
   const std::wstring&     s,
   wchar_t                 delimiter,
   splitX::empties_t       empties = splitX::empties_ok )
{
  std::wistringstream ss(s);
  ...
}

关于c++ - 错误 C2893 : Failed to specialize function template C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10909955/

相关文章:

arrays - 如何将驼峰式字符串拆分为 awk 中的数组?

c++ - 如何将此 curl 命令转换为 libcurl

c++ - 旋转矩阵特征库

C++如何检查给定输入是否存在于对 vector 中?

linux - 替代创建多部分 .tar.gz 文件?

Excel VBA 在第二个空格后拆分

c++ - 使用 LLVM pass 加载和存储变量

c++ - 使用 SSE 在 C++ 中将两个 32 位整数 vector 相乘的最快方法

c - strcat 与 strncat - 什么时候应该使用哪个函数?

string - 用带有符号的 bash 拆分字符串