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
,但我在实践中几乎没有看到这一点。在处理使用这些类型或由这些类型使用的类型和函数的层次结构时,事情也变得相当复杂。
答案 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
最后,它是关于你作为类型设计者的意图,类/结构应该如何表现。