2012-01-05 42 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