模板上下文中的"不明确的基类"错误

"Ambiguous base class" error in template context

本文关键字:基类 错误 不明确 上下文      更新时间:2023-10-16

我有这个函数模板:

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

为什么会发生此错误?我没有看到任何歧义,"模棱两可的基类"错误通常发生在多重继承情况下,不是吗? 如何使我的代码编译(正确推断模板参数(?

请注意,我无法编辑ABCS类及其相互关系,我只能编辑我的函数f()以正确接受这些类。

编译器不确定是将arg的类型推断为B<A>还是S<A>。我不确定这种特定情况,但众所周知,MSVC 违反了标准,尤其是在模板方面。

至于你的函数,你需要通过显式转换为适当的基础来自己解决这种歧义:

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

或者通过显式指定模板参数:

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

通常,每当语言中存在任何歧义时,编译器永远不会自动解决它,因为它只是对用户意图的猜测,在某些情况下可能是对的,而在另一些情况下则完全错误。