Templates D中的结构和元组模板参数
是否可以编写单个模板函数来递增不同结构的(数字)字段?例如:Templates D中的结构和元组模板参数,templates,d,template-meta-programming,Templates,D,Template Meta Programming,是否可以编写单个模板函数来递增不同结构的(数字)字段?例如: struct Color { ubyte a,r,g,b; } struct Point { double x, y; } 我试过这样的方法: T update(T, A)(T t, A a) if (is(T == struct)) { auto vals = t.tupleof; foreach (i; 0 .. vals.length) { vals[i] += a; // e
struct Color
{
ubyte a,r,g,b;
}
struct Point
{
double x, y;
}
我试过这样的方法:
T update(T, A)(T t, A a)
if (is(T == struct))
{
auto vals = t.tupleof;
foreach (i; 0 .. vals.length) {
vals[i] += a; // error: i cannot be read at compile time
}
return T(vals); // convert back to struct
}
我也尝试过编写接受元组的函数模板,但是元组总是被扩展的,这会阻止编译器匹配正确的模板。
谢谢。好吧,我想说你正在尝试做的事情很奇怪,但这肯定是可能的。最天真、最恰当的方式可能是:
void update(T)(ref T t)
if(is(T == struct))
{
foreach(ref var; t.tupleof)
++var;
}
使用副本执行此操作的最简单方法可能是复制它,然后对其进行更新,而不是尝试使用更新的值构造一个新的副本(尽管我相信如果您真的愿意,也可以这样做):
当然,这里的主要问题是,这两个方面的模板约束都太弱了。你所要做的就是在你的结构中有不可增删的类型,它就不能工作了。修复此问题的最简单方法可能是创建一个同名模板来为您测试它:
T update(T)(T t)
if(isIncrementableStruct!T)
{
auto copy = t;
foreach(ref var; copy.tupleof)
++var;
return copy;
}
template isIncrementableStruct(T)
{
enum isIncrementableStruct = is(T == struct) &&
is(typeof({T t; foreach(var; t.tupleof) ++var;}));
}
如果您希望能够增加所有可增加的字段,而不需要增加其他字段,您可能会执行以下操作:
T update(T)(T t)
if(is(T == struct))
{
auto copy = t;
foreach(ref var; copy.tupleof)
{
static if(canIncrement!(typeof(var)))
++var;
}
return copy;
}
template canIncrement(T)
{
enum canIncrement = is(typeof({T var; ++var;}));
}
在任何情况下,您似乎错过的主要事情是在使用ref
时尝试直接迭代tupleof
,以便更新元素,而不是更新元素的副本
T update(T)(T t)
if(is(T == struct))
{
auto copy = t;
foreach(ref var; copy.tupleof)
{
static if(canIncrement!(typeof(var)))
++var;
}
return copy;
}
template canIncrement(T)
{
enum canIncrement = is(typeof({T var; ++var;}));
}