错误 C2893:无法专门化函数模板 C++
Posted
技术标签:
【中文标题】错误 C2893:无法专门化函数模板 C++【英文标题】:error C2893: Failed to specialize function template C++ 【发布时间】:2012-06-06 07:30:38 【问题描述】:我尝试创建如下所示的字符串拆分模板,但出现错误。
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;
当我尝试将它与如下矢量类一起使用时,标题中的错误会失败:
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];
【问题讨论】:
【参考方案1】:好的,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);
...
【讨论】:
别忘了错别字! 我认为这不是假装成为模板之神。如果一种编程语言具有在这种情况下有用的特性(避免代码重复),为什么不使用它呢? 然后就可以使用第一个代码示例了。查看我添加的一些修复。 添加了另一种 STL 风格的方法。 @Forgottn:他能把签名改成template <typename Container, typename StringType = typename Container::value_type> Container& split(... typename StringType::value_type delimiter, ...)
吗?【参考方案2】:
目视检查您的代码,我并没有真正发现任何问题。我对您的程序进行了剪切和粘贴,在您的测试代码周围添加了 main
并编译了它(FC 15 上的股票 g++)。
编译器在您的 split
函数中发现了一个错字。 split::no_empties
应该是 splitX::no_empties
。此外,在启用警告的情况下,它报告for
循环正在比较有符号类型和无符号类型。
在修正错字和编译器警告后,例程编译并运行良好。
【讨论】:
请评论否决票,以便我知道要改进的地方。谢谢! 不幸的是,这不是一个真正的答案,但这看起来更好。请指定您的编译器。以上是关于错误 C2893:无法专门化函数模板 C++的主要内容,如果未能解决你的问题,请参考以下文章