ええと、あなたがやろうとしていることはかなり奇妙だと思いますが、それは確かに可能です。最も素朴なインプレースの方法は、おそらく次のようになります。
void update(T)(ref T t)
if(is(T == struct))
{
foreach(ref var; t.tupleof)
++var;
}
コピーを使用してそれを行う最も簡単な方法は、おそらく、更新された値で新しいものを構築しようとするのではなく、コピーしてから更新することです(ただし、本当に必要な場合は、それも実行できると確信しています)。
T update(T)(T t)
if(is(T == struct))
{
auto copy = t;
foreach(ref var; copy.tupleof)
++var;
return copy;
}
もちろん、ここでの主な問題は、これらの両方に対するテンプレートの制約が非常に弱いことです。あなたがしなければならないのはあなたの構造体にインクリメントできないタイプを持っていることだけであり、それは機能しません。これを修正する最も簡単な方法は、おそらくそれをテストするための同名のテンプレートを作成することです。
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;}));
}
いずれにせよ、あなたが見逃しているように見える主なことは、要素のコピーを更新するのではなく、要素を更新するために、tupleof
使用中に直接反復を試みることでした。ref