D - 静态,如果变量参数不能正常工作

时间:2017-08-27 18:53:24

标签: d

假设我有以下可变参数函数,哪个作用是将一个路径从片段连接起来(每个片段可以是整数类型的索引,也可以是字符串类型的节点):

string 
makePath(P...)(P path)
{
    import std.conv;
    import std.format;

    string res;
    foreach (piece; path) {
        pragma(msg, typeof(piece).stringof);
        static if (is(piece: size_t))
            res = res is null ? piece.to!string : format("%s[%s]", res, piece);
        else if (is(piece: string))
            res = res is null ? piece : format("%s.%s", res, piece);
        else
            static assert(0);
    }
}

如果我以后像这样使用它:string path = makePath("foo", "bar"),代码会以某种方式到达static assert(0);并且编译终止。这是最奇怪的,但是pragma实际上将string写为第一个参数的类型,尽管事实上采用了其他类型的代码路径。

更好的是,使用makePath(12, 13)导致编译器抱怨 字符串的行<(关于不兼容类型的int和{{ 1}})和string。这是怎么回事?

我在DMD和LDC都试过这个。

1 个答案:

答案 0 :(得分:1)

is关键字在这里有问题。 (我发现这是一个令人困惑的关键词......)

我建议您使用std.traits中的模板来测试类型,大部分内容都包含在内:https://dlang.org/phobos/std_traits.html

这是您的功能的工作版本:

string 
makePath(P...)(P path)
{
    import std.conv;
    import std.format;
    import std.traits : isSomeString, isNumeric;

    string res;
    foreach (piece; path) {
        static if (isNumeric!(typeof(piece)))
            res = res is null ? piece.to!string : format("%s[%s]", res, piece);
        else static if (isSomeString!(typeof(piece))) // Note, you were missing the 'static' on the 'else if' part
            res = res is null ? piece : format("%s.%s", res, piece);
        else
            static assert(0);
    }
    return res;
}

unittest {
    static assert(makePath("foo","bar") == "foo.bar");
    static assert(makePath("foo","bar",1) == "foo.bar[1]");
}