Visual Studio 2013。
假设:
class base_1
{
public:
virtual void foo(int) = 0;
};
class base_2
{
public:
virtual void foo(int, double) = 0;
};
class join_1_2 : public virtual base_1, public virtual base_2
{};
我有一个水槽:
void sink(join_1_2 ¶m)
{
param.foo(42, 3.14);
}
但是我得到以下编译器错误:
错误C2385:'foo'的模糊访问
可以是基础'base_1'中的'foo'
或者可能是基础'base_2'中的'foo'
错误C2660:'base_1 :: foo':函数不带2个参数
错误C3861:'foo':找不到标识符
我知道我可以通过以下方式解决此问题:
param.base_2::foo(42, 3.14);
但是你可以想象,虚拟继承已经是我必须忍受的太多罪。我可能会写一个适配器。但是我不明白是什么阻止了编译器尝试在base_2中解析foo。我的同事认为这是一个编译错误,但我不是那么快就责怪供应商。
C ++规范如何解决跨基类解析重载虚拟方法的问题?
答案 0 :(得分:4)
根据标准确实存在歧义,但您可以使用using
或明确指定基类:
class join_1_2 : public virtual base_1, public virtual base_2
{
public:
using base_1::foo;
using base_2::foo;
};
void sink(join_1_2 ¶m)
{
param.base_2::foo(42, 3.14);
}
7.3.3使用声明
出于重载解析的目的,将using声明引入的函数 派生类将被视为派生类的成员。
答案 1 :(得分:4)
经验法则是,不同范围内的函数不会超载 - 这里我们的Unique
处于不同的范围内。如果您希望它们超载,您需要使用 using-declaration 来引入它们:
foo