2017-07-14 12 views
1

私のコードでは、演算子< <を使用して変数を取り、それに従って変数を処理するクラスを作成しています。クラス内に入る正確なロジックは、簡潔さのために、明瞭度&のために省略されています。匿名オブジェクトのoperator <<を使用できません

私が直面してる問題は、私は、オブジェクトの匿名のインスタンスを作成し、(< <)オペレータと直接それを使用しようとすると、ほとんどのコンパイラは文句を言うだろうということです - なし(の線に沿って何かを私が理解から「オペレータ< <」)

の一致、直接クラスを呼び出す(TestObject()は)法的な表現であり、それはオペレータに渡される匿名のオブジェクトをインスタンス化する必要があります。

なぜこれがコンパイルされないのか考えてみてください。

typedef unsigned int uint32; 

class TestObject 
{ 
public: 
    TestObject() 
     : mValue(0) 
    { 
    } 

    uint32 GetValue() const 
    { 
     return mValue; 
    } 

private: 
    uint32 mValue; 
}; 

template <typename T> 
TestObject& operator<<(TestObject& o, const T& t) 
{ 
    return o; 
} 

void TestObjectTest() 
{ 
    TestObject myTestObject; 
    uint32 newValue = 123; 
    const uint32 resultValue = (myTestObject << newValue).GetValue(); // This compiles for both visual studio 2013 and gcc. 
    const uint32 resultValue2 = (TestObject() << newValue).GetValue(); // Compiles using visual studio 2013, but does not compile using x86-64 gcc 6.2: "no match for 'operator<<' in 'TestObject() << newValue' 
} 

int main(void) 
{ 
    TestObjectTest(); 
    return 0; 
} 
+0

あなたが最初のソリューションは、明示的なキャストを必要とすることに注意してください、私はそれがVS – Borgleader

答えて

3

TestObject()一時的TestObjectが得られます。それは一時的なものではないので、左辺参照(except for MSVS's evil extension)にバインドすることはできません。あなたのオペレータがTestObjectを変更する必要がない場合、単にそれがconst&を取るために変更することは十分です:

template <typename T> 
const TestObject& operator<<(const TestObject& o, const T& t) 
{ 
    return o; 
} 

あなたが値を変更する必要がある場合、あなたは別のオーバーロードを追加し、右辺値参照に取る必要があります。これは、一時的に結合し、あなたがそれを変更することができます:

template <typename T> 
TestObject& operator<<(TestObject&& o, const T& t) 
{ 
    return o; 
} 
+1

でコンパイル驚いている非constの参照に一時的に結合することができるはずの戻り時にconstenceを削除します。 –

+0

@ Jean-BaptisteYunèsよろしくお願いします。私は 'const 'を返すように変更しました。 – NathanOliver

+0

rvalue参照パラメータへの参照を返すことは有効ですか?一時的な議論が破壊された場合、これは「ぶら下がった」参考資料ではありませんか? – zett42

関連する問題