【发布时间】:2011-06-18 22:46:22
【问题描述】:
我有一个非常简单的解析器规则(用于 AXE),如下所示:
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 的推导类型不应该总是与初始值设定项完全相同吗?
AXE 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));
}
我无法将问题简化为一个简短的测试用例,不幸的是,每次我尝试提供简单示例时,它都会编译。
【问题讨论】:
-
我们是否知道问题在于初始化
auto变量,或者它是否是&运算符之一的临时问题? -
@Bo Persson:看起来问题出在
auto,因为这行:space & space & space;编译没有问题。查看错误消息,编译器正确识别了右侧类型,但由于某种原因决定为auto分配不同的类型,从而导致转换错误。 -
这似乎与
auto无关,但事实上R1在您的第二个&中使用(E & space,其中E是右值第一次使用&的结果似乎是T&,而不是T(根据C++0x 的要求)。现在对我来说闻起来像是 GCC 问题。 -
@Johannes Schaub:是的,看起来编译器错过了右值,但即便如此,为什么它在
auto的右侧和左侧会有不同的类型? -
@Gene 问题不在于
auto,我想。返回表达式的类型与operator&的第二个实例化的返回类型不匹配。但这表明R1在operator&的主体中与声明部分中的类型不同。如果您将operator&更改为使用auto name() -> ...表示法,会有什么不同吗?只是猜测......