c++ - C++ 17 可以处理嵌套的可变参数模板吗?

标签 c++ variadic-templates c++17

<分区>

考虑下面的 C++ 17 代码,它测试一组枚举值以查看该组中是否包含另一个枚举值:

enum Flag { val1, val2, val3, val4, val5 };

template<Flag arg> struct Value {
    template<Flag... set> struct IsIn {
        static constexpr bool value =
            static_cast<bool>(((set == arg) || ...));
    };
};

这按预期工作:

bool x = Value<val4>::IsIn<val1, val2, val5>::value;
// x == false

bool y = Value<val2>::IsIn<val3, val2>::value;
// y == true

但是,我想测试是否所有一组值都包含在另一组中,如下所示:

template<Flag... args> struct Values {
    template<Flag... set> struct AreIn {
        static constexpr bool value =
            static_cast<bool>((Value<args>::IsIn<set...>::value && ...));
    };
};

以上代码无法在 GCC 7.3 或 Clang 5.0 上编译;他们都给出了相当隐晦的答案,几乎没有深入了解问题。鉴于模板参数列表中的参数包扩展是允许的(只要模板支持扩展),我很难弄清楚为什么这不是合法的 C++。

最佳答案

您遇到了 C++ 语法中最令人恼火的问题之一:不可推断的 dependent names .

当你做 Foo<Bar>::Baz<Quux> , 自 Foo<Bar>是从属名称,您必须输入 template Baz 之前的关键字为了防止解析器从悬崖上跑下来。 Clang 通常非常擅长通过有用的错误明确地告诉您这一点,但在某些情况下(例如您的情况)它只是爆炸并说 Expected )或同样无益的事情。

有关详细信息,请参阅 this other question

因此,修复模板所需要做的就是添加 template依赖模板调用的关键字:

template<Flag... args>
struct Values {
    template<Flag... set>
    struct AreIn {
        static constexpr bool value =
            static_cast<bool>((Value<args>::template IsIn<set...>::value && ...));
    };
};

另请注意,static_cast<bool>()是多余的。

关于c++ - C++ 17 可以处理嵌套的可变参数模板吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48680048/

相关文章:

c++ - 二进制 32 float (IEEE) 中的前导位

c++ - C++中的值比较结果

c++ - 将 std::filesystem::path 传递给函数段错误

c++ - 我如何在 win xp 下在运行时提升我的进程

c++ - 正确同步的 C++ 代码

c++ - Qt,没有命名的信号?

c++ - 初始化和访问可变类模板的成员

c++ - 可变参数宏中的模板推导失败

c++ - 用于获取多个容器引用的可变参数模板

c++ - 通过从函数返回值 move 的大括号初始化给出 "excess elements"错误