我有这个函数,extract()
,它取一个范围和一个成员的名字,然后尝试创建一个包装范围,其front()
只提供对指定成员的访问。
问题在于Range.front()
,当R的形式为const(T)[]
时。编译器指示函数r.front()
不存在。我非常确定非const
R和const r.front()
之间的相互作用有问题,但我不确定如何解决它。
那么,我的直觉是否正确?在任何一种情况下,究竟是什么问题,我该如何解决?
auto extract (string member, R)(R range) {
import std.traits: hasMember;
import std.range: ElementType, isInputRange;
static assert(hasMember!(ElementType!R, member));
static assert(isInputRange!R);
struct Range {
R r;
bool empty ()() { return r.empty; }
void popFront ()() { r.popFront; }
ElementType!R front () { mixin("return r.front." ~ member ~ ";"); }
}
return Range(range);
}
第一。如果你想保留你的实现,你应该替换
import std.range: ElementType, isInputRange;
上
import std.range: ElementType, isInputRange, front;
和
ElementType!R front () { mixin("return r.front." ~ member ~ ";"); }
上
auto front () { mixin("return r.front." ~ member ~ ";"); }
但。您的实现过于复杂
它可能更简化。
只是
auto extract1 (string member, R)(R range)
if((hasMember!(ElementType!R, member)) && isInputRange!R)
{
return range.map!("a." ~ member);
}
事实证明,如果你打算使用数组,你需要std.range.primitives.front()
,并且因为名字尽可能紧密地绑定,所以没有名称冲突(如果R
实现front()
它被调用而不是来自std.range
的那个)。
但是,由于我不明白的原因,您无法有选择地导入它。你必须导入所有的std.range.primitives
。
在任何情况下,给定一个结构S
:
struct S {
string name;
}
还有一个数组:
const(S)[] a = [S("A"), S("B")];
正确调用test.extract!"name"()
返回["A", "B"]
。