2012-01-05 45 views
3

为什么X中的方法测试模糊不清,以及如何解决这个问题?在函数重载中使用标签

struct A{}; 
struct B{}; 

template<typename T> 
struct I { void test(T){} }; 
struct X : public I<A>, I<B> {}; 

int main(int argc, const char *argv[]) 
{ 
    X x; 
    x.test(A()); 
    return 0; 
} 

编译错误:

In function ‘int main(int, const char**)’: 
error: request for member ‘test’ is ambiguous 
error: candidates are: void I<T>::test(T) [with T = B] 
error:     void I<T>::test(T) [with T = A] 
+0

您是否暗示当前代码含糊不清,并且无法编译,即此代码修复了歧义,但您不喜欢该样式,什么? – Useless 2012-01-05 12:48:44

+0

@无用,我已经详细阐述了这个问题,澄清一下 – Allan 2012-01-05 12:57:53

回答

6

test是不明确的,因为它是X两个基类中的一员。虽然不是两个函数都匹配,但名称匹配。

修正与明确的前进:

struct X : public I<A>, I<B> { 
    template <typename T> 
    void test(T t) { I<T>::test(t); } 
}; 
+1

+1是的,这是要走的路。比我的答案更加用户友好。 – 2012-01-05 12:59:27

+0

@ ltn100:谢谢,尽管我更喜欢PlasmaHH的'使用'。 :-) – thiton 2012-01-05 13:00:27

+0

它的可读性略高一些,但您必须为每个新的基类添加一条新的使用语句。我不是多重继承的拥护者,但它似乎是OP的功能。 – 2012-01-05 13:59:04

1

因为X多重继承I<A>I<B>,调用test()是模糊的。你可以这样做是为了明确声明你指的是哪一方:使用

struct A{}; 
struct B{}; 

template<typename T> 
struct I { void test(T){} }; 
struct X : public I<A>, I<B> {}; 

int main(int argc, const char *argv[]) 
{ 
    X x; 
    x.I<A>::test(A()); 
    return 0; 
} 
3

用途:

struct A{}; 
struct B{}; 

template<typename T> 
struct I { void test(T){} }; 
struct X : public I<A>, I<B> 
{ 
    using I<A>::test; 
    using I<B>::test; 
}; 

int main(int argc, const char *argv[]) 
{ 
    X x; 
    x.test(A()); 
    return 0; 
} 

gcc的错误request for member 'test' is ambiguous是不是真的是最好的在这里,我们可以看到更好的是什么意思有铿锵的错误:member 'test' found in multiple base classes of different types

+0

thiton的转发方式意味着你编写10个转发函数,而不是100个使用语句。 – Useless 2012-01-05 13:04:40

+0

@Useless:OP问题未指定,以选择哪种解决方案更好;如果真正的问题需要转发更复杂/不寻常的类型,则需要更加小心,至少要使用C++ 11所谓的“完美转发”。但即使如此,如果重载需要函数指针,并且将重载函数传递给测试函数,那么转发将不会帮助您在那里使过载与选择的函数参数匹配。 – PlasmaHH 2012-01-05 13:44:32