Может ли автоматическое удержание типа вызвать ошибку преобразования? - PullRequest
9 голосов
/ 19 июня 2011

У меня очень простое правило синтаксического анализатора (для 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 оператор перегрузки & вот так:

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 ]

3 голосов
/ 27 ноября 2011

auto не всегда точно тип инициализатора, потому что auto отбрасывает ссылки, делая его тип T там, где вы ожидаете T&. Если вам нужна ссылка - заклинание auto&.

2 голосов
/ 19 мая 2012

Не оценивайте этот ответ, это только для информационных целей

Это действительно было ошибкой в ​​предыдущих версиях gcc, она была исправлена ​​в gcc-4.7.0.

0 голосов
/ 02 октября 2011

Попробуйте взять компилятор на слове, с этой версией:

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 ;

Что происходит?

Отредактировано, чтобы добавить: Я только что заметил, что этому вопросу три месяца. Так что не бери в голову. Но удалось ли это когда-нибудь решить?

0 голосов
/ 02 октября 2011

Проблема в ссылках.

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>&>& для второго. Это несоответствие аргумента шаблона - возможно, в возвращаемом значении. Скорее всего, это происходит из-за того, что реализация SFINAE в Visual Studio в лучшем случае является хитрой, и она не реализует двухфазный поиск должным образом, и возможно, что версия GCC выбирает другую перегрузку для Visual Studio.

...