5

職場で遭遇したばかりの状況について質問があります。

セットアップ: 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++ の名前解決規則を十分に理解していませんが、これを見ると、Trim の呼び出しがあいまいであるように思われます

驚くべきことは、GCC を使用して impl.cpp で定義された関数を呼び出して、Linux 上で問題なくコンパイルできることです。ネイティブ コンパイラを使用して HP-UX でコンパイルすると、呼び出しが stringStuff.h で定義されているものとして解決され、一時参照を非 const 参照に変換することについて不平を言うようです (これは驚くべきことに、エラーではなく警告です)。 、および void を myString に割り当てようとすることについて。

C++ 標準に従って何が起きているはずですか? また、どのコンパイラ (どちらかである場合) がそれを正しく行っているのでしょうか?

ところで、私の場合は、trim の呼び出しの前に :: を付けて「修正」しましたが、これは実際には理想的ではありません。

4

1 に答える 1

2

秘訣は、一方が const 参照を取り、もう一方が非 const 参照を取ることです。したがって、それらは 2 つの異なる関数であり、解決があいまいになる可能性がある同じ関数ではありません。次に、呼び出しのパラメーターの型が何であるかに行き着きます。substr は値を返すため、const 参照にのみバインドできます。したがって::Trim、警告なしで呼び出す必要があります。HP-UX コンパイラは間違っていると思います。

于 2012-11-09T00:51:06.290 に答える