Вызов перегруженной функцией ref-qualifiers функции неоднозначен

Я обнаружил странное поведение при компиляции моего кода с помощью G ++ (gcc 4.8.1 и MinGW 4.8.2 с -std=gnu++1y флаг). В духе SSCCE я выделил следующий фрагмент:

struct C
{

    template< typename X >
    auto
    f(X &&) const &
    { ; }

    template< typename X >
    auto
    f(X &&) &
    { ; }

    template< typename X >
    auto
    f(X &&) &&
    { ; }

};

int main()
{
    int i{};
#if 1
    C{}.f(i);
#endif
#if 1
    C c{};
    c.f(i);
#endif
    return 0;
}

Выдает ошибку:

main.cpp: In function 'int main()':
main.cpp:29:10: error: call of overloaded 'f(int&)' is ambiguous
     c.f(i);
          ^
main.cpp:29:10: note: candidates are:
main.cpp:6:5: note: auto C::f(X&&) const & [with X = int&]
     f(X &&) const &
     ^
main.cpp:11:5: note: auto C::f(X&&) & [with X = int&]
     f(X &&) &
     ^
main.cpp:16:5: note: auto C::f(X&&) && [with X = int&]
     f(X &&) &&
     ^

Но в случае #if 1 а также #if 0, или же #if 0 а также #if 1 компилируется нормально. Также если я заменю все autoс voids, то все тоже успешно компилируется.

Это ошибка или просто мое заблуждение?

1 ответ

Решение

g++ 4.8.2 имеет ту же проблему с еще более простым ( Live at coliru):

struct A {
    auto f() & {}
    auto f() && {}
};

int main() {
    A{}.f();
    A a;
    a.f();
}

несмотря на то, что программа явно правильная. Кажется, это ошибка во взаимодействии между ref-квалификаторами и выводом типа возврата: предположительно, процесс дедукции удаляет квалификаторы из неявного аргумента объекта перед передачей их для разрешения перегрузки.

Я сообщил об этом как ошибка GCC 60943.

Другие вопросы по тегам