2014-03-31 15 views
0

我正在將一個多平臺項目代碼從VS2003移植到VS2013。VS2013過載錯誤(不會發生在gcc中)

我遇到了一個我無法理解的錯誤。

這是一個測試代碼,說明它:

using namespace std; 

class MyString : public string { 

public: 

    MyString() : string() {}; 
    MyString(const string &a_path) : string(a_path) {}; 
    MyString(const MyString &a_path) : string(a_path) {}; 

    friend MyString operator+(const MyString& path, const string& s) { 
     string str(path); 
     return str + s; 
    }; 
}; 

void test() { 

    MyString result; 
    MyString one; 

    result = one + string("aaa"); // error C2666 } } 

該代碼可以用VS2003和gcc的幾個(新)版本進行編譯。 的VS2013編譯器抱怨,出現以下錯誤:

1>mystring.cpp(22): error C2666: 'operator +' : 3 overloads have similar conversions 
1>mystring.cpp(12): could be 'MyString operator +(const MyString &,const std::string &)' [found using argument-dependent lookup] 
1> [...]\xstring(2411): or 'std::basic_string<char,std::char_traits<char>,std::allocator<char>> std::operator +<char,std::char_traits<char>,std::allocator<char>>(std::basic_string<char,std::char_traits<char>,std::allocator<char>> &&,std::basic_string<char,std::char_traits<char>,std::allocator<char>> &&)' 
1> [...]\xstring(2401): or 'std::basic_string<char,std::char_traits<char>,std::allocator<char>> std::operator +<char,std::char_traits<char>,std::allocator<char>>(std::basic_string<char,std::char_traits<char>,std::allocator<char>> &&,const std::basic_string<char,std::char_traits<char>,std::allocator<char>> &)' 
1> [...]\xstring(2391): or 'std::basic_string<char,std::char_traits<char>,std::allocator<char>> std::operator +<char,std::char_traits<char>,std::allocator<char>>(const std::basic_string<char,std::char_traits<char>,std::allocator<char>> &,std::basic_string<char,std::char_traits<char>,std::allocator<char>> &&)' 
1> [...]\xstring(2321): or 'std::basic_string<char,std::char_traits<char>,std::allocator<char>> std::operator +<char,std::char_traits<char>,std::allocator<char>>(const std::basic_string<char,std::char_traits<char>,std::allocator<char>> &,const std::basic_string<char,std::char_traits<char>,std::allocator<char>> &)' 
1> while trying to match the argument list '(MyString, std::basic_string<char,std::char_traits<char>,std::allocator<char>>)' 
1> note: qualification adjustment (const/volatile) may be causing the ambiguity 

類在我的項目是基礎類之一,在整個項目中使用。所以我正在尋找一個不會影響很多代碼的解決方案。

+0

我認爲這是因爲'MyString'繼承自'std :: string'。編譯器無法在'operator +(const MyString&,const std :: string&)'和'operator +(const std :: string&,const std :: string&)'之間進行選擇。 –

+4

不要繼承std容器。導致太多麻煩。如果需要,使用'operator std :: string'來創建自己的獨立MyString類。 –

+0

編寫新代碼時我不會這樣做。在這種情況下,我正在維護一個以這種方式完成的舊項目。 很奇怪gcc爲什麼允許它,VS2013沒有。 我也不想修改幾百行代碼來改變這個類,因爲繼承的變化。 – Urban

回答

0

問題的正確解決方案是使用不同的參數實現運算符。

所以符聲明應該是:的

MyString operator+(const string& path, const string& s); 

代替:

MyString operator+(const MyString& path, const string& s); 

這可能是一個問題,如果它的實施將需要訪問類的MyString的一些功能。但對我而言,情況並非如此。

感謝@Arne Mertz指點我正確的方向。

1

給你不必當前的代碼(這意味着不應該)使運營商類的朋友,因爲它並不需要訪問私有成員:

class MyString : public string { 

public: 

    MyString() : string() {}; 
    MyString(const string &a_path) : string(a_path) {}; 
    MyString(const MyString &a_path) : string(a_path) {}; 
}; 

MyString operator+(const MyString& path, const string& s) { 
    string str(path); 
    return str + s; 
}; 

然而,儘管這威力解決你的問題,我應該提到像std::string這樣的標準庫類並不意味着來源於,所以你應該考慮其他手段(例如聚合而不是繼承)來實現你的目標。這也可能有助於解決您的問題,因爲編譯器不會將MyString視爲std::string,並因可用的過載而感到困惑。另外,我希望在類的定義之前使用using指令只是爲了簡潔起見,因爲在頭文件中使用命名空間範圍的指令很少是件好事。

更新:在operator+實施更緊密看,你可能想徹底離開它,因爲它做什麼的operator+接受兩個std::string的已經爲你做。

+0

如果我要編寫一個新代碼,或者改變類使用聚合的影響不會導致更改100行代碼,那麼您的答案是可以接受的。 還有其他建議嗎? – Urban

+0

你試過免費的非朋友'operator +'嗎?您只需更改「MyString」的標題並僅重新編譯包含該標題的文件。 –

+0

friend關鍵字不會改變任何內容。 – Urban

相關問題