const成员函数应该返回const还是非const?

时间:2013-01-25 22:32:19

标签: const d

struct Type
{
  auto opBinary(string op)(Type other) const {
    return Type();         // #1 return type is Type
    return typeof(this)(); // #2 return type is const(Type)
  }
}

unittest
{
  Type t1, t2;
  auto t3 = t1 + t2;
}

t1.opBinary!("+")(t2)中,t1成为常量,而t2保持非常量。 opBinary的返回类型应为Type还是const(Type),为什么?

const(T)是超类型,所以也许它应该返回const,但我在实践中几乎没有看到这一点。在处理使用这些类型或由这些类型使用的类型和函数的层次结构时,事情也变得相当复杂。

2 个答案:

答案 0 :(得分:4)

由于这里的返回值是一个新对象,我说它是非const的。作为新的,它可以安全地修改,所以没有理由用const不必要地限制它。

如果您要返回现有对象的一部分,那么您将要使用inout而不是const。 inout表示对象的constness也将返回返回值。

inout(Type) opBinary(string op)(Type other) inout {
    return whatever;
}

现在如果使用const(Type)对象,返回也将是const,如果在可变对象上调用它,则返回也是可变的。

答案 1 :(得分:1)

应该返回类型是T还是const(T)?任何都可以。

哪一个更好?取决于您的预期行为。

opBinary上的

const 限定符仅表示隐藏的“this”参数为 const 。没有别的,没有别的。它并不意味着返回类型。这一切归结为非常简单的选择:

struct Type
{
    int a;
    auto opBinary(string op)(Type other) const
           if (op == "+")
    {
        return Type(this.a + other.a);
    }
}

void main()
{
    Type first, second;
    (first + second).a = 42; // Do you want to allow this?
                             // Yes -> return non-const
                             // No -> return const
}

如果您想保留参数的限定符,请使用 inout (请参阅Adams答案)或手动检查限定符以获取更复杂的选项。

任何一种选择都要记住自动类型扣除:

auto third = first + second;
third.a = 42; // Error if returns const

Type fourth = first + second;
fourth.a  = 42; // Fine in both cases, struct was copied

最后,它是关于你作为类型设计者的意图,类/结构应该如何表现。