3

我正在从MSVCto移植一个项目,Borland C++但在template functions. 例如,以下

void fn(const char *buffer)
{
  vector<string> output;
  boost::split(output, string(buffer), is_any_of(","));
  // ...

导致编译器错误:

[BCC32 Error] example.cpp(208): E2285 Could not find a match for 'split<SequenceSequenceT,RangeT,PredicateT>(vector<string,allocator<string> >,string,is_any_ofF<char>)'

而修改后的例子

void fn(const char *buffer)
{
  vector<string> output;
  string sBuffer(buffer);
  boost::split(output, sBuffer, is_any_of(","));
  // ...

编译得很好。

如文章标题所示,这个问题的概括是,在某些情况下BCC,如果参数作为在函数参数列表中构造的临时对象传入,则似乎与模板函数不匹配。

在更改所有受影响的代码之前,我想了解为什么BCC认为第一个示例是错误的。这是编译器的缺陷,还是我的代码不符合C++标准?

我正在使用RAD Studio / C++ Builder XE2.

4

2 回答 2

3

来自 Boost 手册

template<typename SequenceSequenceT, typename RangeT, typename PredicateT> 
  SequenceSequenceT & 
  split(SequenceSequenceT & Result, RangeT & Input, PredicateT Pred, 
        token_compress_mode_type eCompress = token_compress_off);

似乎该函数确实通过引用获取其参数,因此您的“解决方法”实际上是使用它的正确方法。

众所周知,MSVC 允许绑定到非常量引用作为“扩展”。

于 2012-09-25T12:33:11.427 回答
3

这不是因为函数是模板;而是因为函数是模板。这是因为由于某种原因,它将其Input参数作为非const 左值引用,如此所述:

template<typename SequenceSequenceT, typename RangeT, typename PredicateT> 
  SequenceSequenceT & 
  split(SequenceSequenceT & Result, RangeT & Input, PredicateT Pred, 
        token_compress_mode_type eCompress = token_compress_off);

在标准 C++ 中,您不能将临时右值(例如 )绑定string(buffer)到此类引用。在微软对语言的富有想象力的重新诠释中,您可以。

解决方案是完全按照您所做的:引入一个可以通过引用传递的命名非临时变量。

于 2012-09-25T12:34:35.993 回答