首页 > 后端开发 > C++ > 正文

为什么在 C 中调用可变参数模板成员函数时会出现多重继承歧义?

Susan Sarandon
发布: 2024-10-25 01:50:30
原创
829 人浏览过

Why Does Multiple Inheritance Ambiguity Occur in C   When Calling a Variadic Template Member Function?

消除多个继承类成员的歧义

考虑以下可变参数基类模板:

<code class="cpp">template <typename... Types>
class Base {
public:
    template <typename T>
    typename std::enable_if<Contains<T, Types...>::value>::type
    foo() { std::cout << "Base::foo()\n"; }
};
登录后复制

foo()只能使用与类型包中的类型之一匹配的模板参数来调用成员。现在,让我们定义一个具有不重叠基类型的派生类:

<code class="cpp">struct Derived : public Base<int, char>, public Base<double, void> {};</code>
登录后复制

调用 Derived().foo() 应该直观地解析为 Base 。基类。然而,编译器抱怨歧义。

为什么编译器无法解决歧义:

成员查找 [class.member.lookup] 的合并规则指出,当派生类具有空声明集(无成员),必须合并所有基类的查找集。在我们的例子中,基类具有不同的声明集,因此合并失败。

解决方案:

为了避免这种歧义,我们可以向派生类添加 using 声明class:

<code class="cpp">struct Derived : public Base<int, char>, public Base<double, void> {
    using Base<int, char>::foo;
    using Base<double, void>::foo;
};</code>
登录后复制

通过在派生类中引入 foo 的重载,我们有效地绕过了合并规则。

使用收集器类:

或者,我们可以使用模板类来聚合来自所有基类的 using 声明:

<code class="cpp">template <typename... Bases>
struct BaseCollector;

template <typename Base, typename... Bases>
struct BaseCollector<Base, Bases...> : Base, BaseCollector<Bases...> {
    using Base::foo;
    using BaseCollector<Bases...>::foo;
};

struct Derived : BaseCollector<Base2<int>, Base2<std::string>> {};</code>
登录后复制

这种方法在 C 17 中编译效率更高,因为它允许对 using 声明进行包扩展。

以上是为什么在 C 中调用可变参数模板成员函数时会出现多重继承歧义?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!