我正在将一个项目从MSVC
移植到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
.
这不是因为函数是一个模板; 这是因为出于某种原因,它将其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)
)绑定到此类引用。在Microsoft对语言的富有想象力的重新诠释中,你可以。
解决方案是完全按照你所做的去做:引入一个可以通过引用传递的命名的非临时变量。
来自 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 允许作为"扩展"绑定到非常量引用。