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 对象相当简单,通过引用传递或对象本身无关紧要,但如果 R​​ef 是更复杂和沉重的东西,那么它可能最终会成为一个问题。

所以,我问人们他们对上述内容的看法……并给出一些建议。显然,您可以构造 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 有一个扩展,允许将对非常量的引用绑定到临时对象。这是非标准行为。Gcc 没有这样的扩展并且理所当然地抱怨。

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

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

显然,您可以构造 Ref 并通过引用传递,或者更改运算符重载以获取对象而不是引用。

如果您需要Ref在调用operator>>. 前者是要走的路。

于 2013-09-30T11:20:08.483 回答
1

问题是您试图将临时绑定到非常量左值引用,这在标准 C++ 中是不允许的。Visual Studio 有一个扩展,可以让你的代码编译,而 GCC 坚持标准。

您可以通过不传递临时参数来完全绕过该问题:

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