隐式强制转换不适用于BOOST_STRONG_TYPEDEF和BOOST_SPIRIT_DEBUG_NODE

Implicit cast doesn't work for BOOST_STRONG_TYPEDEF and BOOST_SPIRIT_DEBUG_NODE

本文关键字:BOOST TYPEDEF SPIRIT DEBUG NODE STRONG 转换 不适用 适用于      更新时间:2023-10-16

我定义了一个提升::精神::气规则:

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<< 时隐式从标识符转换为 std::string ?或者是否有限制阻止编译器在尝试匹配其他运算符(即operator<<)时应用某个类型的强制转换运算符?

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

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

我正在使用 gcc4.4.2

这与

提升、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在这里看起来可能有点例外,它可以做加宽/缩小。 虽然主题不同