2011-01-28 142 views
8

我編譯此代碼與海灣合作委員會(4.2.1蘋果打造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&) 

我不瞭解此代碼含糊不清的原因;這兩種方法有不同的簽名。

+0

我很驚訝,鐺可以編譯你的代碼,而GCC抱怨。 – peoro 2011-01-28 19:06:40

回答

6

修改c這種方式:

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

C++(之前的C++ 0x)是在繼承功能種別扭:如果提供一個函數與一個基類的功能的相同的名稱它隱藏基礎類的。

它看起來也從兩個類繼承有同樣的問題。

//尋找標準...

1

它是不明確的,因爲你傳入一個整數常量,可能(可能)被傳送到std::size_tindex類型。更改main以下內容,它應該解決它:

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

    return 0; 
} 

隨着中說,它極有可能,你不應該在這裏使用多重繼承。

+1

整數不能被轉換爲索引類型。如果你嘗試編譯,它不起作用。 – 2011-01-28 18:39:44

+0

@mattia:你必須對問題更具體。通過你所展示的,上面的代碼將起作用(顯然,如果你需要另一個操作員,你必須改變角色)。 @peoro:`static_cast`完全是他在這裏做的 - 將一個整數轉換爲特定的類型。 – 2011-01-28 18:44:24

6

名稱解析重載決議之前完成。
c中沒有operator(),因此編譯器會在其基類中尋找operator(),並且在a中找到一個,並且在b中找到一個使名稱不明確(並且不會發生重載解析)。

如果要消除歧義的名稱,你可以顯式調用a::operator()vc.a::operator()(1);