【问题标题】:C++ template parameter inheritanceC++模板参数继承
【发布时间】:2021-10-17 17:57:18
【问题描述】:

我遇到了一些代码 sn-ps,一个类可以通过其模板参数从另一个类继承。但是,我不明白为什么我需要在struct D 中有三个using 行。我尝试调用dsay_hi() 函数,但它声明error: request for member ‘say_hi’ is ambiguous,如果我有三个using 行,错误就消失了。谁能告诉我为什么?

struct C1 {
  void say_hi(int) { puts("int hi"); }
};
struct C2 {
  void say_hi(char) { puts("char hi"); }
};
struct C3 {
  void say_hi(double) { puts("double hi"); }
};
template<typename T, typename U, typename V>
struct D : T, U, V { 
  using T::say_hi;
  using U::say_hi;
  using V::say_hi;
};
D<C1, C2, C3> d;

【问题讨论】:

  • 您可以在没有usings 的情况下手动指定使用哪个 BTW:d.C1::say_hi(1) 将调用say_hi(int)。我不确定usings 是如何清除存在的歧义的,但这可能与那个有关。
  • 执行using T::say_hi;using U::say_hi;using V::say_hi; 会将say_hi 的重载从C1C2C3 带入D。没有它们,编译器将无法判断您指的是d.C1::say_hid.C2::say_hi 还是d.C3::say_hi

标签: c++ templates inheritance template-inheritance


【解决方案1】:

这是隐藏规则在 c++ 中如何工作的一个变体:https://isocpp.org/wiki/faq/strange-inheritance#hiding-rule。但是您实际上没有在 D 中声明任何可能重载基类方法的方法。 C++ 编译器不会在整个继承树中搜索函数调用的所有可能重载,而是在找到正确的重载时停止(遵守标准)。要修改编译器的这个基本工作,您可以添加using 声明来指定哪些重载应该可见或解决歧义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-10
    • 1970-01-01
    • 2018-11-11
    相关资源
    最近更新 更多