自动类型扣除可能导致转换错误?

时间:2011-06-18 22:46:23

标签: c++ g++ c++11

我有一个非常简单的解析器规则(对于AX),如下所示:

auto space = axe::r_lit(' ');
auto spaces = space & space & space;

最后一行在VC2010中编译并按预期工作,但在gcc 4.6中给出了一个奇怪的错误:

parsers.cpp:68:34: error: conversion from 
'axe::r_and_t<
    axe::r_and_t<axe::r_char_t<char>&, axe::r_char_t<char>&>, 
    axe::r_char_t<char>&
>' to non-scalar type 
'axe::r_and_t<
    axe::r_and_t<axe::r_char_t<char>&, axe::r_char_t<char>&>&, 
    axe::r_char_t<char>&
>' requested

我想知道,它是否是gcc中的(已知)错误,以及是否有可能通过auto声明获得转换错误。 auto的推导类型不应该与初始化器的类型完全相同吗?

AX overloads operator&是这样的:

template<class R1, class R2>
r_and_t<
    typename std::enable_if<
       is_rule<typename std::remove_reference<R1>::type>::value, R1>::type, 
    typename std::enable_if<
       is_rule<typename std::remove_reference<R2>::type>::value, R2>::type
>
operator& (R1&& r1, R2&& r2)
{
    return r_and_t<R1, R2>(std::forward<R1>(r1), std::forward<R2>(r2));
}

我无法将问题简化为一个简短的测试用例,不幸的是每次我尝试用简单的例子来编译它。

4 个答案:

答案 0 :(得分:3)

auto并不总是完全符合初始值设定项的类型,因为auto正在删除引用,使其T类型为T&。如果您需要参考 - 拼写auto&

答案 1 :(得分:2)

请勿对此答案评分,仅供参考

这确实是以前版本的gcc中的一个错误,它已在gcc-4.7.0中修复。

答案 2 :(得分:0)

问题出在参考文献中。

parsers.cpp:68:34: error: conversion from 
'axe::r_and_t<
    axe::r_and_t<axe::r_char_t<char>&, axe::r_char_t<char>&>, 
    axe::r_char_t<char>&
>' to non-scalar type 
'axe::r_and_t<
    axe::r_and_t<axe::r_char_t<char>&, axe::r_char_t<char>&>&, 
    axe::r_char_t<char>&
>' requested

第一个模板参数为第一个模板参数axe::r_and_t<axe::r_char_t<char>&, axe::r_char_t<char>&>,第二个模板参数为axe::r_and_t<axe::r_char_t<char>&, axe::r_char_t<char>&>&。这是模板参数不匹配 - 可能在返回值中。最有可能的是,它发生的原因是Visual Studio的SFINAE实现充其量是狡猾的并且它没有正确实现两阶段查找,并且GCC版本可能会为Visual Studio选择不同的重载。

答案 3 :(得分:0)

尝试使用此版本的编译器:

axe::r_and_t<
axe::r_and_t<axe::r_char_t<char>&, axe::r_char_t<char>&>, 
axe::r_char_t<char>&
> spaces = space & space & space ;

会发生什么?

编辑添加:我刚刚注意到这个问题已经过了三个月。所以没关系。但它有没有得到解决?