2012-11-09 110 views
5

我有一個關於我剛剛在工作中遇到的情況的問題。關於C++名稱查詢的澄清

設置:在stringStuff.h

namespace n1 
{ 
namespace n2 
{ 
    typedef std::string myString; 
} 
} 

namespace n1 
{ 
namespace n2 
{ 
    void LTrim(myString& io_string); 
    void RTrim(myString& io_string); 

    inline void Trim(myString& io_string) 
    { 
     LTrim(io_string); 
     RTrim(io_string); 
    } 
} 
} 

在impl.cpp

#include "stringStuff.h" // This actually gets included via other include files 
#include "globalInclude.h" // contains 'using namespace n1::n2;'. Yes, I know this isn't best practice 

inline static myString Trim(const myString& in_string) 
{ 
    // impl 
} 

static void impl(const myString& in_string, myString& out_string) 
{ 
    size_t N = 10; // just some computed value. 
    out_string = Trim(in_string.substr(1, N)); // This is the line with the error 
} 

現在,我承認我不懂C++名稱解析的規則相當以及我應該,但當我看到這一點時,似乎打電話給修剪應該不明確。

令人驚訝的是,它使用GCC在Linux上編譯得很好,調用impl.cpp中定義的函數。當我使用其本地編譯器在HP-UX上進行編譯時,它似乎將調用解析爲stringStuff.h中定義的調用,並且抱怨將臨時變換轉換爲非const變量(這是令人驚訝的警告,而不是錯誤) ,並試圖將void分配給myString。

根據C++標準應該發生什麼,以及哪個編譯器(如果有的話)是否正確?

順便說一句,我'固定'在我的情況下,通過前綴調用::修剪,雖然這不是很理想。

回答

2

訣竅是一個需要一個const引用,另一個是非const引用,所以它們是兩個不同的函數,而不是同一個函數,其分辨率可能不明確。然後回到調用中參數的類型。由於substr返回一個值,它只能綁定到const引用。所以它應該叫::Trim沒有警告。我會說HP-UX編譯器是錯誤的。

+0

那麼你可以重載參數的常量?我不知道。 – Bwmat

+1

@Brmat它們被認爲是相同類型的不同派生物,因此具有不同的結果類型,從而有資格對重載進行簽名鑑定。 – WhozCraig