2012-11-09 24 views
5

私はちょうど仕事中に来た状況について質問があります。C++の名前検索の明確化

セットアップ:

#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 
} 

今impl.cppで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); 
    } 
} 
} 

で 、私は、私は非常にだけでなく、私がすべきのようにC++の名前解決のルールを理解していない認めるが、これを見ると、Trim の呼び出しがのようにあいまいになっているようです。

驚くべきことは、LinuxでGCCを使ってうまくコンパイルし、impl.cppで定義された関数を呼び出すことです。ネイティブコンパイラを使用してHP-UXでコンパイルすると、stringStuff.hで定義されているものとしてコールが解決されたように見えますが、一時的なものをconst以外のものに変換することについて不平を言います(これは驚くべきことですが、 myStringにvoidを代入しようとすると、

C++標準に従って何が行われるべきですか、どのコンパイラ(どちらか一方の場合)が正しくなっていますか?

私の場合は、トリムの呼び出しに接頭辞::を付けて固定しましたが、これは本当に理想的ではありません。

答えて

2

トリックは、const参照と非const参照をとるので、それらは2つの異なる関数であり、解像度があいまいである可能性がある同じ関数ではありません。次に、コールのパラメータのタイプを調べます。 substrは値を返すので、const参照にのみバインドできます。したがって、警告なしで::Trimを呼び出す必要があります。私は、HP-UXコンパイラが間違っていると言います。

+0

パラメータの定数にオーバーロードすることはできますか?私はそれを知らなかった。 – Bwmat

+1

@Bwmatこれらは同じタイプの異なる派生物とみなされ、結果として異なるタイプの結果とみなされ、それによって過負荷に対する署名の適格性を認定します。 – WhozCraig