GCC/VS2008: Другое поведение вызова функции, когда шаблонный базовый класс получен из себя

Следующий код работает с Visual Studio 2008, но не с GCC/G ++ 4.3.4 20090804. Какое поведение - согласно стандарту C++ - корректно?

template <int N>
struct A : A<N-1> {};

template <>
struct A<0> {};

struct B : A<1> {};

template <int N>
void Func(const A<N> &a) {}

int main()
{
    A<1> a;   //is derived from A<0>
    Func(a);  //vs2008: ok, g++: ok
              //Comeau: ok

    B b;      //is derived from A<1>
    Func(b);  //vs2008: ok, g++: error, no matching function for call to Func(B&)
              //Comeau: error: no instance of function template "Func" matches the
              //        argument list. The argument types that you used are: (B).

    return 0;
}

Если я перегружаю Func () с

void Func(const A<0> &a) { std::cout << '0'; }
void Func(const A<1> &a) { std::cout << '1'; }

всегда последний называют (как ожидалось). Таким образом, я также ожидал бы, что шаблонная функция будет названа с N=1, потому что <1> прямая основа B. Это предположение действительно неправильно?

13
задан user287715 8 March 2010 в 11:45
поделиться

2 ответа

Покопавшись в N3035, я нашел это в разделе 14.9.2.1.4:

Если P является классом, а P имеет вид простой-шаблон-id, то преобразованный A может быть производным классом выведенного A Аналогично, если P является указателем на класс в форме простой-шаблон-id, преобразованный A может быть указателем на производный класс, на который указывает выведенный A.

Однако в 14.9.2.1.5 он говорит:

Эти альтернативы рассматриваются только в том случае, если в противном случае определение типа не удалось бы. Если они дают более одного возможного вывода A, вывод типа не выполняется.

Это так: оба A <1> и A <0> считаются базовыми классами для B .

Полагаю, это означает отказ от Visual Studio (по крайней мере, если текущий стандарт говорит то же самое: упражнение для читателя).

4
ответ дан 2 December 2019 в 02:11
поделиться

В ISO / IEC 14882 это почти то же самое (14.8.2.1):

  • Если P является классом, а P имеет идентификатор шаблона формы, то A может быть производным классом от выведенный A. Аналогичным образом, если P является указателем на класс идентификатора шаблона формы, A может быть указателем на производный класс, указывающий на {{1} } выведенным A.

Эти альтернативные варианты рассматриваются только в том случае, если в противном случае выведение типа не удалось бы. Если они дают более одного возможного выведенного A, вывод типа не выполняется.

Итак, я согласен с Яном. Кто-нибудь здесь, кто этого не делает?

0
ответ дан 2 December 2019 в 02:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: