我已经定义了一个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
答案 0 :(得分:4)
这与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
在这里可能看起来有点异常,它可以做什么扩大/缩小。不同的主题,但