【问题标题】:Portability issue with template function Instantiation模板函数实例化的可移植性问题
【发布时间】:2012-09-25 12:04:10
【问题描述】:

我正在将一个项目从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

【问题讨论】:

  • “我正在将一个项目从 MSVC 移植到 Borland C++”哦,我很同情你必须受苦的地狱。
  • “我正在将一个项目从 MSVC 移植到 Borland C++”我此时停止阅读。
  • boost::split 是否通过引用、const 引用或值来获取参数?如果是第一个,那么错误是正确的,因为您不能将非const 引用绑定到临时对象。
  • 这只是一个猜测,但如果 boost::split 将引用作为第二个参数,我认为您需要先创建对象并将其传入。
  • 嗯,谢谢你的慰问。如果您想了解详细信息,我正在恢复从 BCC 到 MSVC 的迁移,这已被证明是不可行的......所以它实际上是“地狱又回来了”。

标签: c++ templates c++builder function-templates c++builder-xe2


【解决方案1】:

这不是因为函数是模板;这是因为由于某种原因,它将其Input 参数作为非const lvalue 引用,如记录的here

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))绑定到此类引用。在微软对语言的富有想象力的重新诠释中,您可以。

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

【讨论】:

    【解决方案2】:

    来自 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 允许绑定到非常量引用作为“扩展”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多