Ошибка «Неоднозначный базовый класс» в контексте шаблона - PullRequest
0 голосов
/ 24 июня 2018

У меня есть этот шаблон функции:

template <class TemplateArgument, template<class> class TemplateType>
TemplateArgument f(const TemplateType<TemplateArgument>& arg)
{
    return TemplateArgument();
}

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

struct A {};
template <typename T> struct S {};
template <typename T> struct B : public S<T> {};

struct C : public B<A> {};

int main()
{
    f(C());
    return 0;
}

И сообщение об ошибке:

<source>: In function 'int main()':

<source>:15:10: error: no matching function for call to 'f(C)'

     f(C());

          ^

<source>:2:18: note: candidate: template<class TemplateArgument, template<class> class TemplateType> TemplateArgument f(const TemplateType<TemplateArgument>&)

 TemplateArgument f(const TemplateType<TemplateArgument>& arg)

                  ^

<source>:2:18: note:   template argument deduction/substitution failed:

<source>:15:10: note:   'const TemplateType<TemplateArgument>' is an ambiguous base class of 'C'

     f(C());

          ^

Бывает с GCC (любая версия) и clang (любая версия).Не бывает с MSVC.Демонстрационная версия: https://godbolt.org/g/eWxeHJ

Почему возникает эта ошибка?Я не вижу никакой неоднозначности, ошибка «неоднозначный базовый класс» обычно возникает в ситуациях множественного наследования, не так ли?Как мне скомпилировать мой код (правильно вывести аргументы шаблона)?

Обратите внимание, что я не могу редактировать классы A, B, C, S и их отношение друг к другу.могу только редактировать мою функцию f(), чтобы правильно принимать эти классы.

1 Ответ

0 голосов
/ 24 июня 2018

Компилятор не уверен, следует ли выводить тип arg s как B<A> или S<A>.Я не уверен в этом конкретном случае, но MSVC, как известно, нарушает стандарт, особенно когда речь идет о шаблонах.

Что касается вашей функции, вам необходимо устранить эту неоднозначность самостоятельно, явно приведя к соответствующей базе:

f((const B<A> &)C());

или путем явного указания параметров шаблона:

f<A, B>(C());

Обычно, когда есть какая-либо неоднозначность в языке, она никогда автоматически не разрешается компилятором, потому что это просто предположение очто именно имел в виду пользователь, что может быть правильным в одних случаях и совершенно неверным в других.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...