具有多重继承的operator()的模糊定义

时间:2011-01-28 18:30:57

标签: c++ inheritance operator-overloading

我使用GCC(4.2.1 Apple build 5664)编译此代码

#include <cstddef>

using std::size_t;

template <char I> struct index { };

struct a
{
    void operator()(size_t const &) { }
};

struct b
{
    template <char I>
    void operator()(index<I> const &) { }
};

struct c: public a, public b { };

int main (int argc, char const *argv[])
{
    c vc;
    vc(1);

    return 0;
}

并给我以下错误:

main.cpp: In function ‘int main(int, const char**)’:
main.cpp:22: error: request for member ‘operator()’ is ambiguous
main.cpp:14: error: candidates are: template<char I> void b::operator()(const index<I>&)
main.cpp:9:  error:                 void a::operator()(const size_t&)

我不明白为什么这段代码含糊不清;这两种方法有不同的签名。

3 个答案:

答案 0 :(得分:6)

以这种方式修改c

struct c: public a, public b
{
    using a::operator();
    using b::operator();
};

C ++(在C ++ 0x之前)在继承函数方面有点尴尬:如果你提供一个与基类同名的函数,它会隐藏基类。

看起来继承两个类也有同样的问题。

//寻找标准......

答案 1 :(得分:6)

在重载解析之前完成名称解析 operator()中没有c,因此编译器会在其基类中查找operator(),并在a中找到一个,在b中找到另一个,使名称不明确(并且不会发生重载决定。)

如果您想消除名称歧义,可以明确地致电a::operator()vc.a::operator()(1);

答案 2 :(得分:1)

它的含糊不清是因为你传入的是一个整数常量,可以(可能)被转换为std::size_tindex类型。将main更改为以下内容,它应该解决它:

int main (int argc, char const *argv[])
{
    c vc;
    vc(static_cast<std::size_t>(1));

    return 0;
}

话虽如此,很可能你不应该在这里使用多重继承。