【问题标题】:"Ambiguous base class" error in template context模板上下文中的“不明确的基类”错误
【发布时间】:2018-12-03 04:26:25
【问题描述】:

我有这个函数模板:

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() 以正确接受这些类。

【问题讨论】:

  • 你还需要TemplateType吗? struct C 没有模板化。
  • 编译器不确定是否将args类型推断为B&lt;A&gt;S&lt;A&gt;
  • @r3mus_n0x 一方面我同意你的观点,另一方面编译器不应该选择最衍生的替代方案吗?
  • @navyblue 我不希望它自动执行标准中未明确指定的任何操作。我从未读过或听说过这样的模板推导规则。
  • @r3musn0x: 哦,我现在明白了……我也希望它能够推断出最派生的类。您认为编译器不需要自动推断这种情况是 C++ 标准中的错误吗?还是因为某种原因,这样的扣除与现行标准不兼容?

标签: c++ templates c++14 language-lawyer c++17


【解决方案1】:

编译器不确定是否将args 类型推断为B&lt;A&gt;S&lt;A&gt;。我不确定这个具体案例,但众所周知,MSVC 违反了标准,尤其是在涉及模板时。

至于您的功能,您需要通过显式转换为适当的基数自行解决这种歧义:

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

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

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

通常,只要语言中存在任何歧义,编译器永远不会自动解决它,因为这只是对用户究竟想要什么的猜测,在某些情况下可能是正确的,而在其他情况下可能完全错误。

【讨论】:

  • @VioletGiraffe,第二个参数是一个模板模板参数,所以应该是f&lt;A, B&gt;(C()),也就是应该替换为一个未实例化的模板名。
  • 谢谢,今天学到了一些关于模板推演的新知识(以及注意细节的重要性!)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-26
  • 2015-09-21
  • 1970-01-01
  • 1970-01-01
  • 2019-02-01
  • 2022-11-18
相关资源
最近更新 更多