对于BOOST_STRONG_TYPEDEF和BOOST_SPIRIT_DEBUG_NODE隐式转换不起作用 [英] Implicit cast doesnt work for BOOST_STRONG_TYPEDEF and BOOST_SPIRIT_DEBUG_NODE

查看:402
本文介绍了对于BOOST_STRONG_TYPEDEF和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;&LT; ?或者是有没有prevents编译应用类型的​​转换运算符时,它试图以匹配其他运营商的限制(即运营商的LT;&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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆