对于BOOST_STRONG_TYPEDEF和BOOST_SPIRIT_DEBUG_NODE隐式转换不起作用 [英] Implicit cast doesnt work for BOOST_STRONG_TYPEDEF and BOOST_SPIRIT_DEBUG_NODE
问题描述
我已经定义了一个boost ::精神::补气规则:
的boost ::精神::齐::规则<迭代器,标识()> ID;
,其中标识符被定义为:
BOOST_STRONG_TYPEDEF(标准::字符串,标识符)
但是当我使用
BOOST_SPIRIT_DEBUG_NODE(ID);
它失败,下面的错误编译:
boost_1_51_0 /升压/精神/主页/支持/ attributes.hpp:1203:错误:不对应的运营商的LT;<'在出LT&;< VAL
和它列出的ostream的重载运算符。
明知BOOST_STRONG_TYPEDEF定义转换运算符原始类型,不应该
编译器标识符隐式转换为std :: string使用时运营商的LT;<
?或者是有没有prevents编译应用类型的转换运算符时,它试图以匹配其他运营商的限制(即运营商的LT;<
)<? / p>
在我定义了以下操作员它编译:
内联的std :: ostream的&放大器;运营商的LT;≤(的std :: ostream的和放大器; OS,常量标识符和ID)
{
返回OS&LT;&LT;的static_cast&LT;的std ::字符串常量和放大器;&GT;(ID);
}
我使用gcc4.4.2
这无关与提升,strong_typedef或精神的。
它有很多事情要做型扣除模板参数。简言之,当参数类型推导,隐式转换从不的发生[1]
比照:
的#include&LT;&iostream的GT;
#包括LT&;串GT;
#包括LT&;升压/ strong_typedef.hpp&GT;BOOST_STRONG_TYPEDEF(双,X)
INT的main(){性病::法院LT&;&LT; X(); }
没问题!替换双击
按的std ::字符串
,它不工作了。有什么不同?
流媒体运营商的声明有所不同。
对比
的ostream&安培; :: ostream的运营商的LT;≤(双);
要
模板&LT; typename的_CharT,typename的_Traits,类型名_Alloc&GT;
内嵌basic_ostream&LT; _CharT,_Traits&GT;&安培;
运营商所述;≤(basic_ostream&下; _CharT,_Traits&GT;&放大器;, basic_string的&下; _CharT,_Traits,_Alloc&GT;常量&安培)
这是运算符重载是的函数模板的事实不允许任何隐式转换。
[1]我想 initializer_list
可能看起来好像有点例外的在这里,有什么用加宽/缩小,它可以做。不同的主题,虽然
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)
but when I use
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'
and it lists the overloaded operators of ostream.
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);
}
I am using gcc4.4.2
This has nothing to do with boost, strong_typedef or spirit.
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(); }
No problem! Replace double
by std::string
, and it doesn't work anymore. What's different?
The declaration of the streaming operator differs.
Contrast
ostream& ostream::operator<<(double);
To
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] 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屋!