Я обнаружил странное поведение при компиляции моего кода с G ++ (НКУ 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
с void
s, то все тоже успешно компилируется.
Это ошибка или просто мое заблуждение?
g ++ 4.8.2 имеет такую же проблему с еще более простым (Жить в колиру):
struct A {
auto f() & {}
auto f() && {}
};
int main() {
A{}.f();
A a;
a.f();
}
несмотря на то, что программа явно правильная. Кажется, это ошибка во взаимодействии между ref-квалификаторами и дедукцией возвращаемого типа: предположительно, процесс дедукции удаляет квалификаторы из неявного аргумента объекта перед передачей их для разрешения перегрузки.
Я сообщил об этом как GCC bug 60943.