如果您需要在D中重写以下C++代码,您将如何做?
struct A{
const S* _s;
B _b;
C _c;
mutable C _c1, _c2;
A(const B& b, const C& c, const S* s){ /*...*/ }
void compute(const R& r) const
{
//...
_c1 = ...
_c2 = ...
}
};
D没有
mutable
,根据我的经验,它很少在C++中使用。但是,假设出于正确的原因使用了mutable
,我在D中的选择是什么?
最佳答案
您有三种选择来处理此问题:
const
。这将使编译器崩溃,但是不能保证您的代码将按预期工作。特别是,如果您从多个线程中在同一对象上调用该函数,那么您将受到数据争夺的摆布。 struct A
{
static C[const(A)*] _c1s, _c2s;
void compute(ref const(R) r) const
{
_c1s[&this] = ...
_c2s[&this] = ...
}
}
我使用
&this
作为外部哈希表的键,但是使用某种唯一的ID可能会更好。这是一个非常丑陋和棘手的解决方案。我不喜欢另外,请注意,哈希表是线程本地的,因此同一对象在不同线程上将具有不同的值。这对于您的特定应用程序可能是不希望的。 const
。在D中,
const
是可传递的,并且是按位的,即不支持逻辑const。这样做的目的是保证不会发生并发共享数据写入。即使您的代码在逻辑上可能是const正确的,但如果两个线程试图在同一对象上调用compute
,它仍然会中断,因此D不允许这样做,并且不提供任何合法转义(不提供mutable
)。本质上,仅当它们是按位const时,才应将它们标记为
const
。这样的结果是,在D中使用的
const
比在C++中使用的少得多,因为与逻辑const相比,按位const的使用要少得多。例如,考虑一个简单的(无意义的)通用
equal
函数,该函数告诉您两个对象是否相等:bool equal(T)(T lhs, T rhs) { return lhs == rhs; }
注意,我还没有将函数参数标记为
const
。这是故意的。测试是否相等不需要按位const-它只需要逻辑const,因此在对象上强制执行D的const级别将受到不必要的限制。正如jA_cOp所说,D社区认为D中的逻辑常量没有好坏之分。当您尝试像C++的const一样使用D的const时,就会出现问题。它们是不一样的,所以不要以相同的方式使用它们!如果完全有可能某个函数需要使用逻辑const,则不要将它们标记为按位const!
关于class-design - 如何重写在D中使用可变的C++代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8676481/