c++ - 隐式转换不适用于 BOOST_STRONG_TYPEDEF 和 BOOST_SPIRIT_DEBUG_NODE

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

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

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

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

我用的是gcc4.4.2

最佳答案

这与 boost、strong_typedef 或 spirit 无关。

它与模板参数的类型推导有很大关系。简而言之,当推导参数类型时,隐式转换从不发生[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 在这里可能看起来有点像一个异常(exception),它可以扩大/缩小范围。不同的主题,虽然

关于c++ - 隐式转换不适用于 BOOST_STRONG_TYPEDEF 和 BOOST_SPIRIT_DEBUG_NODE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14631508/

相关文章:

python - 将 Python 嵌入到 C++ 中

c++ - 是否可以在控制台中用 C 打印孟加拉语?

c++ - shared_ptr 删除对象

c++ - 队列类中的运算符 <<

c++ - 如何重载三元运算符(?:) in C++?

C++ 运算符 []

c++ - Hinnant 的堆栈分配器和异常

C++:从 cin 流中读取字符串并存储以空格分隔的值

c++ - 捕获微不足道的 boost 异常的奇怪问题

c++ - 连续调用 boost::asio::read_async: 没有数据的回调