can auto type deduction possibly cause conversion error?
I have a very simple parser rule (for AXE), like this:
auto space = axe::r_lit(' ');
auto spaces = space & space & space;
The last line compiles and works as expected in VC2010, but gives a strange error in 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
I wonder, whether it's a (known) bug in gcc, and whether it's even possible to get conversion errors with auto
declaration. Shouldn't the deduced type for auto
be always exactly the same type as the initializer?
AXE overloads operator& like this:
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>::ty开发者_JAVA百科pe
>
operator& (R1&& r1, R2&& r2)
{
return r_and_t<R1, R2>(std::forward<R1>(r1), std::forward<R2>(r2));
}
I wasn't able to reduce the problem to a short test case, unfortunately every time I try to come with simple example, it compiles.
auto
is not always exactly the type of initializer, because auto
is dropping references, making it type T
where you would expect T&
. If you need reference - spell auto&
.
Don't rate this answer, it's for information purposes only
This was indeed a bug in previous versions of gcc, it was fixed in gcc-4.7.0.
The problem is in the references.
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
The first template argument is axe::r_and_t<axe::r_char_t<char>&, axe::r_char_t<char>&>
for the first one, and axe::r_and_t<axe::r_char_t<char>&, axe::r_char_t<char>&>&
for the second. This is a template argument mismatch- probably in the return value. Most likely, it occurs because Visual Studio's SFINAE implementation is dodgy at best and it doesn't implement two-phase lookup properly, and it's possible that the GCC version is picking a different overload to Visual Studio.
Try taking the compiler at its word, with this version:
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 ;
What happens?
Edited to add: I just noticed that this question is three months old. So never mind. But did it ever get resolved?
精彩评论