I'm porting a project from MSVC
to Borland C++
and I'm running into difficulties with template functions
. For example, the following
void fn(const char *buffer)
{
vector<string> output;
boost::split(output, string(buffer), is_any_of(","));
// ...
causes a compiler error:
[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>)'
whereas the modified example
void fn(const char *buffer)
{
vector<string> output;
string sBuffer(buffer);
boost::split(output, sBuffer, is_any_of(","));
// ...
compiles fine.
The generalization of this problem, as indicated in the post title, is that in certain cases BCC
does not seem to match the template function if arguments are passed in as temporary objects that are constructed inside the function's argument list.
Before changing all the affected code, I'd like to understand why BCC
thinks the first example is wrong. Is this a deficiency of the compiler, or does my code not comply to C++
standards?
I'm using RAD Studio / C++ Builder XE2
.
It's not because the function is a template; it's because for some reason it takes its Input
argument as a non-const
lvalue reference, as documented here:
template<typename SequenceSequenceT, typename RangeT, typename PredicateT>
SequenceSequenceT &
split(SequenceSequenceT & Result, RangeT & Input, PredicateT Pred,
token_compress_mode_type eCompress = token_compress_off);
In standard C++, you can't bind a temporary rvalue, such as string(buffer)
, to such a reference. In Microsoft's imaginative reinterpretation of the language, you can.
The solution is to do exactly what you've done: introduce a named, non-temporary variable which can be passed by reference.