0

これは、コードベースで私が抱えている特定の問題というよりも、むしろ意見を求めるものです。次の簡単な例を見てみましょう:-

class Ref
{
    public:
        Ref(char* s, size_t l) : _s(s), _l(l) {}
    private:
        char* _s;
        size_t _l;
};

std::stringstream ss;

char a[256];
ss >> Ref(a, sizeof(a));   // <-------- here is the discussion line

friend std::stringstream& operator>>(std::stringstream& ss, Ref& r)
{
    // perform some functionality
}

Visual Studioを使用すると、上記は正常にコンパイルされます...演算子>>を使用すると、参照を受け取るオーバーライドがあるため、作成されたオブジェクトを参照として渡すことを意味することがわかります。ただし、gcc を使用するとぐらつきます。操作に演算子のオーバーロードがないことを訴えています。

技術的には、オブジェクトを作成し、オブジェクトへの参照ではなく、基本的にオブジェクトをオペレーターに渡すため、gcc は正しいと思います。Microsoftコンパイラがこれを許可する理由、またはgccが参照渡しを意図していることを理解できないのはなぜだろうか? 上記の場合、Ref オブジェクトはかなり自明であり、参照渡しまたはオブジェクト自体はほとんど問題になりませんが、Ref がより複雑で重いものである場合、おそらく問題になる可能性があります。

それで、私は人々に上記についてどう思うか尋ねています...そしていくつかの提案をします. 明らかに、Ref を構築して参照渡しするか、参照ではなくオブジェクトを取るように演算子のオーバーロードを変更することもできますが、実際には、Visual Studio と gcc のこの違いとあなたの意見についての詳細です。

4

3 に答える 3

2

gcc は正しいですconst Ref& r。コンパイルする必要があります。 Ref(a, sizeof(a))一時的なものを作成し、これは定数の左辺値参照にのみバインドできます。Microsoft がコードをコンパイルする理由は、非 const 左辺値参照を一時変数にバインドできるようにする、非準拠の邪悪な拡張機能によるものです。でコンパイルし/W4て、それに関する警告を取得します。

于 2013-09-30T11:19:52.733 に答える
2

MSVC には、非 const への参照を一時オブジェクトにバインドできる拡張機能があります。これは非標準の動作です。Gcc にはそのような拡張機能がなく、当然のことながら文句を言います。

ss >> Ref(a, sizeof(a));
//    ^^^^^^^^^^^^^^^^^^
//    temporary

friend std::stringstream& operator>>(std::stringstream& ss, Ref& r)
//                                  reference to non-const  ^^^^^^  

明らかに、Ref を構築して参照渡しするか、演算子のオーバーロードを変更して、参照ではなくオブジェクトを取ることができます。

Refの呼び出し後に objectを使用する必要がある場合、後者は実際にはオプションではありませんoperator>>。進むべき道は前者です。

于 2013-09-30T11:20:08.483 に答える
1

問題は、標準 C++ では許可されていない非 const 左辺値参照に一時変数をバインドしようとしていることです。Visual Studio にはコードをコンパイルするための拡張機能がありますが、GCC は標準に準拠しています。

一時的なものを渡さないことで、問題を完全に回避できます。

Ref r(a, sizeof(a)); 
ss >> r;
于 2013-09-30T11:20:45.027 に答える