为什么 'using A::X' 不避免多重继承的歧义?
Why doesn't 'using A::X' avoid ambiguity with multiple inheritance?
这与 this question and 相似,但我认为(希望!)不同之处值得解释。
我有一个复杂的配置框架,装饰器 classes 用于实现一些常见的简单操作(例如在调用 class Set 访问器时进行标记)。我正在尝试引入一个新的装饰器(而不是组合),它本身“应该”继承自相同的通用“设置标记”装饰器。
我 运行 变成了“从派生 class 到基础 class 的模棱两可的转换”,我试图解决它的尝试失败了。
我肯定遗漏了一些明显的东西。
这是一个非常简单的示例,没有我所有的框架内容。
class A {
public:
template <class T> void Set(T& arg, T val);
bool Ready() const;
};
class B : private A {
// Does stuff where I want to flag Set() actions
};
class C : public B, public A {
// This class needs the B interface, and the Set()-flagging
public:
void SetParam(double val) { Set(param, val); }
private:
double param;
};
请注意,我最初使用的是 A 的虚拟继承,但实际上我需要将 B 的“设置标志”与 C 的“设置标志”区分开来,因此我进行了上述尝试。
上面的私有继承是我第一次尝试避免歧义。我还尝试在 C:
中引入 using 指令
class C : public B, public A {
// This class needs the B interface, and the Set()-flagging
using A::Set;
using A::Ready;
};
这不会改变错误。我从搜索中了解到,在检查 public/private 状态之前发现了歧义。但我认为显式 using
指令可以解决它。为什么不呢?我是否需要进入并在任何地方显式使用 A::Set(...)
或 A::Ready()
?
两种解决方案。
如果你真的想保留私有和多重继承:
class A {
public:
void Set() {};
bool Ready() const {};
};
class B : private A {
};
class C : public B, public A {
public:
void SetParam() { C::A::Set(); }
};
或者如果不需要,那么一个更简单的:
class A {
public:
void Set() {};
bool Ready() const {};
};
class B : public A {
};
class C : public B {
public:
void SetParam() { Set(); }
};
这与 this question and
我有一个复杂的配置框架,装饰器 classes 用于实现一些常见的简单操作(例如在调用 class Set 访问器时进行标记)。我正在尝试引入一个新的装饰器(而不是组合),它本身“应该”继承自相同的通用“设置标记”装饰器。
我 运行 变成了“从派生 class 到基础 class 的模棱两可的转换”,我试图解决它的尝试失败了。 我肯定遗漏了一些明显的东西。
这是一个非常简单的示例,没有我所有的框架内容。
class A {
public:
template <class T> void Set(T& arg, T val);
bool Ready() const;
};
class B : private A {
// Does stuff where I want to flag Set() actions
};
class C : public B, public A {
// This class needs the B interface, and the Set()-flagging
public:
void SetParam(double val) { Set(param, val); }
private:
double param;
};
请注意,我最初使用的是 A 的虚拟继承,但实际上我需要将 B 的“设置标志”与 C 的“设置标志”区分开来,因此我进行了上述尝试。
上面的私有继承是我第一次尝试避免歧义。我还尝试在 C:
中引入 using 指令class C : public B, public A {
// This class needs the B interface, and the Set()-flagging
using A::Set;
using A::Ready;
};
这不会改变错误。我从搜索中了解到,在检查 public/private 状态之前发现了歧义。但我认为显式 using
指令可以解决它。为什么不呢?我是否需要进入并在任何地方显式使用 A::Set(...)
或 A::Ready()
?
两种解决方案。
如果你真的想保留私有和多重继承:
class A {
public:
void Set() {};
bool Ready() const {};
};
class B : private A {
};
class C : public B, public A {
public:
void SetParam() { C::A::Set(); }
};
或者如果不需要,那么一个更简单的:
class A {
public:
void Set() {};
bool Ready() const {};
};
class B : public A {
};
class C : public B {
public:
void SetParam() { Set(); }
};