隐式强制转换不适用于BOOST_STRONG_TYPEDEF和BOOST_SPIRIT_DEBUG_NODE [英] Implicit cast doesn't work for BOOST_STRONG_TYPEDEF and BOOST_SPIRIT_DEBUG_NODE
问题描述
我已经定义了boost :: spirit :: qi规则:
I have defined a boost::spirit::qi rule:
boost::spirit::qi::rule<Iterator, Identifier()> id;
其中标识符由以下位置定义:
where Identifier is defined by:
BOOST_STRONG_TYPEDEF(std::string, Identifier)
但是当我使用
BOOST_SPIRIT_DEBUG_NODE(id);
它无法编译并出现以下错误:
It fails to compile with following error:
boost_1_51_0/boost/spirit/home/support/attributes.hpp:1203: error: no match for 'operator<<' in 'out << val'
并列出了ostream的重载运算符.
and it lists the overloaded operators of ostream.
知道BOOST_STRONG_TYPEDEF已将演员转换为原始类型时,不应
使用operator<<
时,编译器从标识符隐式转换为std :: string?还是有限制阻止编译器在尝试与其他运算符(即operator<<
)匹配时应用某种类型的强制转换运算符?
Knowing that BOOST_STRONG_TYPEDEF defines a cast operator to the original type, shouldn't
compiler implicitly cast from Identifier to std::string when using operator<<
? or is there a restriction that prevents compiler to apply a cast operator of a type when it is trying to match the other operator (namely operator<<
)?
当我定义以下运算符时,它将进行编译:
When I define the following operator it compiles:
inline std::ostream& operator<<(std::ostream& os, const Identifier& id)
{
return os << static_cast<std::string const&>(id);
}
我正在使用gcc4.4.2
I am using gcc4.4.2
推荐答案
这与boost,strong_typedef或spirit无关.
This has nothing to do with boost, strong_typedef or spirit.
与模板参数的类型推导有很多关系.简而言之,当推导参数类型时,从不进行隐式转换[1]
It has a lot to do with type deduction for template arguments. In short, when argument types are deduced, implicit conversions never take place [1]
cf.
#include <iostream>
#include <string>
#include <boost/strong_typedef.hpp>
BOOST_STRONG_TYPEDEF(double, X)
int main() { std::cout << X(); }
没问题!将double
替换为std::string
,它将不再起作用.有什么不同?
No problem! Replace double
by std::string
, and it doesn't work anymore. What's different?
流操作符的声明不同.
对比度
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&)
运算符重载是功能模板的事实不允许任何隐式转换.
The fact that the operator overload is a function template disallows any implicit conversions.
[1]我猜想initializer_list
在这里可能看起来有点例外,它可以通过加宽/缩小来实现.虽然主题不同
[1] I guess initializer_list
may look like a bit of an exception here, what with widening/narrowing that it can do. Different subject, though
这篇关于隐式强制转换不适用于BOOST_STRONG_TYPEDEF和BOOST_SPIRIT_DEBUG_NODE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!