Я сталкиваюсь с очень раздражающей проблемой, связанной с переходным константой в 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);
}
}
Проблема, с которой я сталкиваюсь, заключается в том, что типы данных 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
}
Код выше не работает. Каков лучший способ заставить это работать? (Конечно, я всегда могу шаблонизировать test()
, но тогда все вариации срезов - const(Slice!(Slice!const(int[])))
и т. Д. - вырастут в геометрической прогрессии, а то и в замешательстве).
Edit:
Есть ли решение, которое работает для struct
s и class
es?