是否可以在编译时将 Foo 转换为 ubyte[size]?

Is it possible to cast Foo to ubyte[size] at compile time?

是否可以在编译时将 Foo 转换为 ubyte[size]

这里有更多的上下文:

struct Algebraic(Types...)
if(Types.length < char.max - 1){
    import std.traits: Largest;
    import std.meta: IndexOf;
    static immutable maxSize = Largest!(Types).sizeof;

    this(T)(in T t)
    if(IndexOf!(T, Types) !is -1){
        type = IndexOf!(T, Types);
        data = *cast(ubyte[maxSize]*)&t;
    }

    void opAssign(T)(in T t)
    if(IndexOf!(T, Types) !is -1){
        type = IndexOf!(T, Types);
        data = *cast(ubyte[maxSize]*)&t;
    }

    inout(T*) peek(T)() inout{
        if(type is IndexOf!(T, Types)){
            return cast(inout(T*))&data;
        }
        return null;
    }
private:
    ubyte[maxSize] data;
    char type = char.max;
}

struct Branch{
    int index;
    int left;
    int right;
}
struct Leaf{
    int index;
}
struct Foo{
    alias Node = Algebraic!(Branch, Leaf);
    Node n = Branch(1,2,3); 
    //Error: cannot convert &const(Branch) to ubyte[12]* at compile time
}

问题是我无法在编译时将 Branch 转换为 ubyte[maxSize]

我不知道有任何 "clean" 方法(会利用 ABI 的编译器知识的方法),因为 CTFE 在防止重新解释方面非常保守。但是,如果这是一个障碍,可以利用 struct ABI 非常简单的事实手动构建字节数组:

import std.traits;

ubyte[T.sizeof] reinterpret (T) ( T x )
    if (!hasIndirections!T)
{
    typeof(return) result;

    static if (is(T == struct))
    {
        size_t offset = 0;
        foreach (ref field; x.tupleof)
        {
            result[offset .. offset + field.sizeof] = reinterpret(field);
            offset += field.sizeof;
        }
    }
    else static if (is(T : ulong))
    {
        for (auto i = 0; i < x.sizeof; ++i)
            result[i] = cast(ubyte) (x >> 8*i);
    }
    else
    {
        // handle floating types, arrays etc.
    }

    return result;
}

struct S
{
    int x, y;
}

static immutable bytes = reinterpret(S(42, 42));

pragma(msg, bytes);

这种方法有一个很大的局限性:您需要手动调整到正确的 ABI。诸如字节顺序之类的东西微不足道,但正确处理字段对齐可能会很痛苦(我什至没有尝试在这个片段中这样做)。