开发者

can auto type deduction possibly cause conversion error?

开发者 https://www.devze.com 2023-03-14 08:17 出处:网络
I have a very simple parser rule (for AXE), like this: auto space = axe::r_lit(\' \'); auto spaces = space & space & space;

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?

0

精彩评论

暂无评论...
验证码 换一张
取 消