【问题标题】:Implicit cast doesn't work for BOOST_STRONG_TYPEDEF and BOOST_SPIRIT_DEBUG_NODE隐式转换不适用于 BOOST_STRONG_TYPEDEF 和 BOOST_SPIRIT_DEBUG_NODE
【发布时间】:2013-01-31 17:20:26
【问题描述】:

我已经定义了一个 boost::spirit::qi 规则:

boost::spirit::qi::rule<Iterator, Identifier()> id;

其中标识符定义为:

BOOST_STRONG_TYPEDEF(std::string, Identifier)

但是当我使用时

BOOST_SPIRIT_DEBUG_NODE(id);

编译失败,出现如下错误:

boost_1_51_0/boost/spirit/home/support/attributes.hpp:1203: error: no match for 'operator<<' in 'out << val'

它列出了ostream的重载运算符。

知道 BOOST_STRONG_TYPEDEF 为原始类型定义了一个强制转换运算符,不应该 使用operator&lt;&lt; 时,编译器从标识符隐式转换为std::string?或者是否存在阻止编译器在尝试匹配另一个运算符(即 operator&lt;&lt; )时应用类型的强制转换运算符的限制?

当我定义以下运算符时,它会编译:

inline std::ostream& operator<<(std::ostream& os, const Identifier& id)
{
    return os << static_cast<std::string const&>(id);
}

我正在使用 gcc4.4.2

【问题讨论】:

  • 当然是static_cast&lt;std::string const&amp;&gt;。否则会发生无意义的复制

标签: c++ boost operator-overloading boost-spirit


【解决方案1】:

这与 boost、strong_typedef 或精神无关。

这与模板参数的类型推导有很大关系。简而言之,当推导参数类型时,隐式转换从不发生[1]

参考:

#include <iostream>
#include <string>
#include <boost/strong_typedef.hpp>

BOOST_STRONG_TYPEDEF(double, X)
int main() { std::cout << X(); }

没问题!将double 替换为std::string,它不再起作用了。有什么不同?

流操作符的声明不同。

对比

ostream& ostream::operator<<(double);

template<typename _CharT, typename _Traits, typename _Alloc>
   inline basic_ostream<_CharT, _Traits>&
   operator<<(basic_ostream<_CharT, _Traits>&, basic_string<_CharT, _Traits, _Alloc> const&)

运算符重载是一个函数模板这一事实不允许任何隐式转换。


[1] 我猜initializer_list 在这里可能看起来有点例外,它可以做什么扩大/缩小。不同的主题,虽然

【讨论】:

  • 我在 c++98 标准中发现了一个与您提到的恕我直言相冲突的示例。但我可能误会了。看看nepsweb.co.uk/langstand/isoCPP/ISO14882/template.html。第 14.8.3 节示例 4. 子类型被强制转换为基类型引用。问题是语句“运算符重载是函数模板的事实不允许任何隐式转换”。是真的,那么为什么根据标准隐式转换为基引用类型是允许的?
  • @amirmonshi 这不是演员表。它只是对同一个对象的多态引用(OO 中的同一个对象identity
  • 不叫upcast吗?但我想我明白你的意思。运算符实际上是一种转换,编译器在推导模板类型时需要格外小心,但向上转换到基引用在某种程度上是“自动的”。
  • 我认为正确的词是:静态。派生的 is-a Base。这种关系是静态已知的。通过多重继承, 可能会进入“向上转换”(用词不当?)实际上是模棱两可的地方。这是您必须在调用代码中指定显式转换的时候。另见例如stackoverflow.com/q/7197887/85371
猜你喜欢
  • 1970-01-01
  • 2014-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多