【问题标题】:Struct and Tuple template parameters in DD中的结构和元组模板参数
【发布时间】:2012-06-09 01:42:08
【问题描述】:

是否可以编写一个模板函数来增加不同结构的(数字)字段?例如:

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
}

我也尝试过编写接受元组的函数模板,但是元组总是被扩展,这会阻止编译器匹配正确的模板。 谢谢。

【问题讨论】:

    标签: templates d template-meta-programming


    【解决方案1】:

    好吧,我想说你正在尝试做的事情很奇怪,但这当然是可能的。最天真、就地的方式可能是:

    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;}));
    }
    

    无论如何,您似乎错过的主要事情是在使用ref 时尝试直接迭代tupleof,以便更新元素而不是更新它们的副本。

    【讨论】:

      猜你喜欢
      • 2023-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多