c++ - 如果类继承自 2 个模板化父类,则调用不明确。为什么?

标签 c++ templates multiple-inheritance visual-c++-2010

我有一个模板类,它对作为模板参数给出的类执行操作。对于我的一些类(class),我想将功能“分组”在一个类(class)中,以使调用者更容易。事实上,代码看起来像这样(名称已更改):

template<typename T>
class DoSomeProcessing
{
public:
   process(T &t);
};

class ProcessingFrontEnd : public DoSomeProcessing<CustomerOrder>, public DoSomeProcessing<ProductionOrder>
{
};

问题是,当我使用 CustomerOrder 作为参数调用 ProcessingFrontEnd::process 时,编译器会报错。

我尝试在较小的测试应用程序中重现该问题。这是代码:

#include <vector>

class X : public std::vector<char>
        , public std::vector<void *>
{
};

int main(void)
{
X x;
x.push_back('c');
return 0;
}

确实,如果编译,Microsoft 的 VS2010 编译器会给出此错误:

test.cpp
test.cpp(11) : error C2385: ambiguous access of 'push_back'
        could be the 'push_back' in base 'std::vector<char,std::allocator<char> >'
        or could be the 'push_back' in base 'std::vector<void *,std::allocator<void *> >'
test.cpp(11) : error C3861: 'push_back': identifier not found

我在调用中使用不同类型(char+void*、double+void*)和不同参数('c',3.14)测试了这个测试应用程序,但错误消息始终相同。

我用 VS2005 和 VS2010 对此进行了测试,但我总是遇到同样的错误。

为什么编译器不能确定要调用的正确函数?是什么让编译器感到困惑?或者它只是 Microsoft 编译器中的错误?

编辑: 如果我明确地向我的类添加 2 个 push_back 方法,如下所示:

class X : public std::vector<char>
        , public std::vector<void *>
{
public:
   void push_back(char c) {}
   void push_back(void *p) {}
};

编译器不再提示了。因此,通过这些方法,他可以清楚地区分字符和空指针。如果两个 push_back 方法是从父级继承的,他为什么不能这样做呢?

最佳答案

这是设计使然。编译器没有尝试解析重载 函数,因为它们没有重载 职能。该标准非常明确 (见 10.2.2)。如果在两个中发现相同的名字 不同的基地,这是一个歧义,即使他们 可以通过调用正确解决(即在 你的情况)。不同类中的同名函数通常具有完全不同的用途,因此不应根据 他们的论据。有很多理由不这样做 允许这样,但这是一个。

假设您的类 C 派生自 A 和 B,并且 这两个基类来自两个不同的 图书馆。如果B的作者增加了一个新的功能 到类,它可能会破坏用户的代码 将调用从 A::foo() 重定向到 B::foo() 如果 后者是更好的匹配。

如果您希望两个函数的处理方式与它们将要处理的方式相同 如果是单个类的一部分,那么最好的方法是使用 派生类中的声明。只需添加

using std::vector<char>::push_back;
using std::vector<void *>::push_back;

X 类的声明。

关于c++ - 如果类继承自 2 个模板化父类,则调用不明确。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3555753/

相关文章:

C++ 将 HTML 代码显示为网站(CGI 程序)

c++ - 用部分模板特化覆盖抽象成员函数

Python:从父类(super class)构造多重继承子类实例

c++ - 是否应该将运算符声明为非成员非模板 friend

Java - 扩展整个类层次结构

c++ - 多重继承、复制构造函数和基类初始化?

c++ - C++中如何指向数组的数组?

c++ - 将 std::mutex 设为静态是否会为互斥体本身创建竞争条件

c++ - 如果在 VC 编译器中包含诸如 std::map 之类的容器,类的内存布局是什么

php - JS 中的模板?