gpt4 book ai didi

d - D 中的 const ref 和 rvalue

转载 作者:行者123 更新时间:2023-12-04 10:11:10 25 4
gpt4 key购买 nike

代码

struct CustomReal
{
private real value;

this(real value)
{
this.value = value;
}

CustomReal opBinary(string op)(CustomReal rhs) if (op == "+")
{
return CustomReal(value + rhs.value);
}

bool opEquals(ref const CustomReal x) const
{
return value == x.value; // just for fun
}
}

// Returns rvalue
CustomReal Create()
{
return CustomReal(123.123456);
}

void main()
{
CustomReal a = Create();
assert(a == CustomReal(123.123456)); // OK. CustomReal is temporary but lvalue
assert(a == Create()); // Compilation error (can't bind to rvalue)
assert(a != a + a); // Compilation error (can't bind to rvalue)
}

编译错误
prog.d(31): Error: function prog.CustomReal.opEquals (ref const const(CustomReal) x) const is not callable using argument types (CustomReal)
prog.d(31): Error: Create() is not an lvalue

http://ideone.com/O8wFc

问题:
  • 为什么const ref 不能绑定(bind)到右值?可以吗?
  • 是否需要从 ref CustomReal 返回 const ref CustomRealopBinary() 才能解决此问题?可以吗?
  • 返回对在堆栈上创建的本地对象的引用是否正确?ref CustomReal Create() { return CustomReal(0.0); }
  • 最佳答案

    refconst ref 之间的唯一区别是 const refconstref 不是。两者都必须带一个变量。两者都不能采取临时措施。这与 C++ 不同,其中 const T& 将采用 T 类型的任何值 - 包括临时值。
    opBinary 不能返回 refconst ref ,因为没有要返回的变量。它正在创造一个临时的。 Create 也是如此。并且使用您要返回的值创建局部变量也无济于事,因为您无法返回对局部变量的引用。它最终会引用一个不再存在的变量。

    您需要在这里做的是添加另一个重载 opEquals :

    bool opEquals(CustomReal x) const
    {
    return value == x.value; // just for fun
    }

    这样,您的代码将编译。

    我会指出,尽管 opEquals 的当前情况确实需要解决一些问题。您会注意到,如果您只有我给您的 opEquals 重载,而不是您当前拥有的重载,则代码无法编译,并且您会收到类似以下的错误:
    prog.d(15): Error: function prog.CustomReal.opEquals type signature should be const bool(ref const(CustomReal)) not const bool(CustomReal x)

    编译器目前对结构体的 opEquals 的确切签名过于挑剔(其他一些函数 - 例如 toString - 也有类似的问题)。这是一个已知问题,可能会在不久的将来得到解决。但是,现在,只需声明 opEquals 的两个重载。如果将 CustomReal 与变量进行比较,则将使用 const ref 版本,如果将 CustomReal 与临时版本进行比较,则将使用其他版本。但如果你两者都有,你应该没问题。

    现在,为什么
    assert(a == CustomReal(123.123456));

    工作,和
    assert(a == Create());  

    没有,我不确定。我实际上希望它们都失败,因为 const ref 不能采取临时措施,但由于某种原因,编译器在这里接受它 - 它可能与它如何处理 opEquals 特殊有关。无论如何,正如我所说, opEquals 和结构存在一些问题需要解决,希望很快就会发生。但与此同时,声明 opEquals 的两个重载似乎可以解决问题。

    编辑: 看来原因是
    assert(a == CustomReal(123.123456));

    工作,和
    assert(a == Create());

    不是因为(出于我不理解的原因)结构文字被认为是左值,而不是 ref 的函数的返回值(不出所料)是右值。有一个 couplebug reports 与之相关,认为结构文字应该是右值,但显然它们是设计的左值(这让我感到困惑)。在任何情况下,这就是为什么使用 const ref 的函数可以使用 struct 文字但不能使用函数的返回值的原因。

    关于d - D 中的 const ref 和 rvalue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6986175/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com