关于D中的传递常数,我遇到了一个非常讨厌的问题.
我有以下代码:
struct Slice(T)
{
T items;
size_t start, length, stride;
this(T items, size_t start = 0, size_t length = size_t.max, size_t stride=1)
{
if (length == size_t.max)
{ length = 1 + (items.length - start - 1) / stride; }
this.items = items;
this.start = start;
this.length = length;
this.stride = stride;
}
Slice!(T) opSlice(size_t a, size_t b)
{
// Everything is fine here
return Slice!(T)(items, start + a * stride, b - a, stride);
}
const(Slice!(T)) opSlice(size_t a, size_t b) const
{
// ERROR! 'items' is const(T), not T.
return const(Slice!(T))(items, start + a * stride, b - a, stride);
}
}
Run Code Online (Sandbox Code Playgroud)
我跑的麻烦是,相当多的数据类型const(Slice!int)和Slice!const(int)和const(Slice!const(int))只是...... 怪异.
如何在opSlice上面重载,返回当前切片的常量副本,随后可以像原始切片一样使用?
换句话说,让我说我有:
void test(in Slice!(int[]) some_slice)
{
//...
}
void main()
{
auto my_slice = Slice!(int[])();
const my_const_slice = my_slice;
test(my_slice); // succeeds
test(my_const_slice); //succeeds
test(my_const_slice[0 .. 1]); // fails
}
Run Code Online (Sandbox Code Playgroud)
上面的代码不起作用.使它工作的最佳方法是什么?(我当然可以总是模板化test(),但是然后所有的切片变化 - const(Slice!(Slice!const(int[])))等等 - 都会成倍增长,而且容易引起混淆.)
有适用于structs 和 class es 的解决方案吗?
将构造函数更改为
inout this(inout T items, size_t start = 0, size_t length = size_t.max, size_t stride=1)
{
if (length == size_t.max)
{ length = 1 + (items.length - start - 1) / stride; }
this.items = items;
this.start = start;
this.length = length;
this.stride = stride;
}
Run Code Online (Sandbox Code Playgroud)
inout为此创建了关键字,它允许参数的const-ness/immutability传播到结果
小智 3
如果 Slice 是一个类,则 inout 也适用:
class Slice(T)
{
T items;
size_t start, length, stride;
this(){}
inout this(inout T items, size_t start = 0, size_t length = size_t.max, size_t stride=1)
{
if (length == size_t.max)
{ length = 1 + (items.length - start - 1) / stride; }
this.items = items;
this.start = start;
this.length = length;
this.stride = stride;
}
inout(Slice!(T)) opSlice(size_t a, size_t b) inout{
return new inout(Slice!T)(items, start + a * stride, b - a, stride);
}
}
void test(in Slice!(int[]) some_slice)
{
//...
}
void main()
{
auto my_slice = new Slice!(int[])();
const my_const_slice = my_slice;
test(my_slice); // succeeds
test(my_const_slice);//succeeds
test(my_const_slice[0 .. 1]); // succeeds
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
279 次 |
| 最近记录: |