【问题标题】:Address of return value of method方法返回值地址
【发布时间】:2015-12-21 18:12:37
【问题描述】:

我有一个返回值的 get 方法:

int Foo::getValue() const
{
    return value_;
}

我正在使用以下代码将此值写入二进制文件:

void Bar::write(const Foo& foo)
{
    /* some code... */

    file_.write(reinterpret_cast<char*>(&foo.getValue()), sizeof(int));
}

而且似乎一切正常。但我不确定 &foo.getValue() 的事情。会不会一直返回getValue()的返回值地址,还是有什么陷阱?

EDIT1:我不想为此创建一个临时变量。

EDIT2:是的,它可以编译并且工作正常。

EDIT3: write 是 ostream::write

EDIT4:使用 /Wall 和 /Za 将无法编译:错误 C2102: '&' requires l-value

【问题讨论】:

  • reinterpret_cast&lt;char*&gt;(&amp;foo.getValue()) 这对我来说似乎很危险。 std::string 不仅仅是一个空终止的char * ...你不能只使用foo.getValue().c_str()吗?
  • 那甚至不应该编译。如果一个函数按值返回,那么它返回一个右值。您不能获取右值的地址。
  • 请看几本书(你完全错了)
  • 你真的,真的应该为此创建一个临时变量。
  • 传递 /Wall /Za 作为编译选项。

标签: c++ function memory-address


【解决方案1】:

标准禁止您获取右值的地址:https://stackoverflow.com/a/28459180/2642059 不符合标准的编译器可能允许这种行为,但可以肯定的是,这不是跨平台的行为,也不能保证即使在对编译器的更新可能更符合 C++ 标准。

由于您不是为特定编译器编程,而是为 C++ 编程,因此找到适用于特定编译器的东西不应该是您的目标。在标准内找到一种方法来实现这一点会更好。

这样做的几个简单选择是:

  1. 通过将其分配给临时值将其转换为左值。他们是免费的!编译器会直接优化它们
  2. getValue 的返回值更改为const int&amp;,这将允许您使用左值。由于ints 通常是按值复制的,因此这可能不会对您的代码库产生影响,但它可以
  3. 创建另一个可以直接返回 (const char*)&amp;value_ 的方法,但是你可能会在滥用这个方法时遇到麻烦,所以要小心

【讨论】:

    【解决方案2】:

    无论出于何种原因,Microsoft 编译器都有一个“功能”——它隐式地将临时转换为左值。您可以通过以下代码检查它:

    int &ref = foo.getValue();
    

    此代码以及您不应该编译的代码。正确的代码是:

    void Bar::write(const Foo& foo)
    {
        /* some code... */
        int temp = foo.getValue();
        file_.write(static_cast<const char*>(&temp), sizeof(int));
    }
    

    【讨论】:

    • 右值可以使用std::addressof() 来解决。问题仍然有效。
    • 为什么要复制?只需int&amp;&amp; ref = foo.getValue() =&gt; &amp;ref
    • @black 可能是 const 引用,但这只是品味问题,我怀疑生成的代码会有什么不同。
    • @BenVoigt 可以吗?当我使用类似于此示例中的std::addressof(foo.getValue()) 的代码时,我收到expression must be lvalue 错误。或者这不是您想到的addressof() 的用法?
    • @spaaarky21:在 C++14 中是可能的,但在 C++17 中添加了新的已删除重载。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    • 2023-03-14
    相关资源
    最近更新 更多