我在处理输出区间,如果每次都调用​​.put(T)​​,则效率太低.

自然,我可为该​​资源​​制作自定义​​OutputRange​​,但我想搞个通用的​​批次调用​​放的​​BufferedOutputRange​​.

在为​​缓冲输出区间​​设计模板时,我先在给定​​输出区间​​上用​​ElementType​​,希望检测允许​​.put(T)​​的类型.但是,我发现​​ElementType​​仅适用于​​输入区间​​.

为此,问题是,用模板好不?假设区间带我可检测到的​​数组​​的​​put​​方法是否安全?思路行不?或者要求程序员显式​​声明输出类型​​,来避免用​​不带数组​​区间?

import std.range;
import std.traits;

// 考虑输出区间的`std.range.ElementType`特化
template ElementType(R)
if (is(typeof(R.put) == function)) // 避免与std.range.ElementType冲突.
{
// 生成代码,非真正的循环
static foreach (t; __traits(getOverloads, R, "put")) {
pragma(msg, "发现放方法,参数=", Parameters!(t).length);
// 已生成代码,用`完成`别名来告诉何时停止
static if (!is(done)) {
// 保存Parameters!(t)失败,重复
static if (Parameters!(t).length == 1 && is(Parameters!(t)[0] T : T[])) {
pragma(msg, "找到数组方法");
// 用T置模板替换为ElementType!(...).
alias ElementType = T;
alias done = bool;
} else static if (Parameters!(t).length == 1 && is(Parameters!(t)[0] T)) {
pragma(msg, "找到单个放");
alias ElementType = T;
alias done = bool;
}
}
}
static if (!is(done)) {
alias ElementType = void;
}
}

unittest {
// 对构单元素放管用.
struct Ham0(T) {
void put(T d) {}
}
assert(is(ElementType!(Ham0!float) == float));

// 有数组放的类,管用
class Ham1(T) {
void put(T[] d) {}
}
assert(is(ElementType!(Ham1!float) == float));

// 忽略分发函数,如支持`单个/数组`放,则元素类型仍然正确
struct Ham2(T) {
void put() {}
void put(float f, T[] d) {}
void put(T[] d) {}
void put(T d) {}
}
assert(is(ElementType!(Ham2!int) == int));
}

​试试​

该方法要求​​调用者​​显式声明输出​​区间​​元素类型,要避免它.

一般按模板实现​​put​​,很难.

问题是,需要吗?在已知​​元素类型​​时,在自己实现的​​放​​中,你的​​BufferedOutputRange​​可用​​是输出区间​​来测试底层​​区间​​,即测试是否可​​批量​​写切片或元素区间,或必须​​调用​​每个元素的​​放​​.

我发现了.在​​Appender和RefAppender​​中的​​放​​,​​算法​​不能检测​​put​​方法.

让用户传入类型,然后检查

isOutputRange!(ORangeT, ElemT) 
//和
is(typeof(ORangeT.init.put([ ElemT.init ])))

.可多种方式满足​​isOutputRange​​.但我想进一步限制只能输出可​​批量放​​的​​流​​.

​自动检测​​很方便,期望​​调用者​​知道插入​​元素类型​​也是合理的.