C ++:成员请求不明确

时间:2017-08-23 12:58:47

标签: c++

#include <iostream>
using namespace std;
class c1{
        public:
                void f(){std::cout<<"In f1\n";}
};
class c2{
        public:
                void f(){std::cout<<"In f2\n";}
};

template <typename T>
class c:public c1, c2 {
    T* pT;
public:
    T* operator->() { return pT; }
};

int main()
{
c<c1>* cMain;
cMain->f();
return 0;
}

错误:

g++ cache.cc
cache.cc: In function ‘int main()’:
cache.cc:22:8: error: request for member ‘f’ is ambiguous
 cMain->f();
        ^
cache.cc:9:8: note: candidates are: void c2::f()
   void f(){std::cout<<"In f2\n";}
        ^
cache.cc:5:8: note:                 void c1::f()
   void f(){std::cout<<"In f1\n";}

为什么不访问模板中指定的c1函数f?我的模板用法错了吗?如何使用模板指向所需的类。?

3 个答案:

答案 0 :(得分:3)

问题是你正在使用指针。您不是在调用c::operator->,而只是取消引用未初始化的cMain并导致UB。删除指针(大多数情况下)修复了问题:

#include <iostream>

class c1{
public:
    void f(){std::cout<<"In f1\n";}
};
class c2{
public:
    void f(){std::cout<<"In f2\n";}
};

template <typename T>
class c { // No longer derives from c1 and c2
    T t; // No longer a pointer
public:
    T* operator->() { return &t; }
};

int main()
{
    c<c1> cMain; // No longer a pointer
    cMain->f(); // Calls c::operator->() now
    return 0;
}

see it work

当然,您不需要c派生c1c2(或任何内容)才能实现此目的。

答案 1 :(得分:2)

如果你不特别需要其他东西的指针语义,你可以添加一个函数到c重定向到正确的基类函数:

template <typename T>
class c:public c1, c2 {
public:
   void f() { T::f(); }
};

答案 2 :(得分:0)

您的通话代码相当于

c<c1>* cMain;
(*cMain).f(); // equivalent to: c<c1> cMain; cMain.f();

*cMain的类型为c<c1>。显然,现在对f()的调用含糊不清,因为c1c2都有f()函数,而c<c1>都继承了它们。模板不应该受到责备(您可以使class c非模板并获得相同的结果。)

如果您想致电->运营商,您应该说(*cMain)->f();,但不要忘记在之前初始化指针。