c++ - 如何使用 C++14 和 C++1z 中的功能缩短此可变参数模板代码?

标签 c++ c++14 variadic-templates template-meta-programming c++17

这是我要用来检查可变参数模板类型是否唯一的代码片段:

template <typename...>
struct is_one_of;

template <typename F>
struct is_one_of<F> {
    static constexpr bool value = false;
};

template <typename F, typename S, typename... T>
struct is_one_of<F, S, T...> {
    static constexpr bool value =
        std::is_same<F, S>::value || is_one_of<F, T...>::value;
};

template <typename...>
struct is_unique;

template <>
struct is_unique<> {
    static constexpr bool value = true;
};

template <typename F, typename... T>
struct is_unique<F, T...> {
    static constexpr bool value =
        is_unique<T...>::value && !is_one_of<F, T...>::value;
};

int main() {
    constexpr bool b = is_unique<bool, int, double>::value;
    constexpr bool c = is_unique<int, char, int>::value;
    static_assert(b == true && c == false, "!");
}

是否有任何方法可以使用 C++14 和 C++1z 中引入的功能使此代码更短和/或更简洁?或者是否有更好的方法来使用新功能实现相同的效果?

在 C++1z 的情况下,我的意思是:最新版本的 Clang 和 GCC 中已经可用的功能。

最佳答案

我们最近添加了 std::disjunction到 C++1z 草案,可用于 is_one_of(一旦找到匹配项,它就会停止实例化,请参阅链接了解更多详细信息):

template <typename F, typename... T>
  using is_one_of = std::disjunction<is_same<F, T>...>;

这已经在 GCC trunk 中实现了。对于旧版本的 GCC,您可以使用实现细节 __or_ 代替:

template <typename F, typename... T>
  using is_one_of = std::__or_<is_same<F, T>...>;

或者使用 C++11 工具手动实现disjunction,如上面链接的提案末尾所示。

关于c++ - 如何使用 C++14 和 C++1z 中的功能缩短此可变参数模板代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34025327/

相关文章:

c++ - memmove 后删除[]期间出现异常

c++ - 避免垂头丧气

c++ - 参数包函数参数可以默认吗?

c++ - 如何 static_assert 给定的函数调用表达式是否可以编译?

c++ - 使用 yaml-cpp 新 API 解析 yaml 文件 - 问题已修复

c++ - 将数据放入 C++ 中的 std::vector 是否会创建数据的拷贝?

c++ - CMake 和 SOIL 链接

c++ - SFINAE 和模板函数实例化 : Why a template argument cannot be deduced when used in function arguments with a SFINAE-enabled type?

c++ - 使类模板化强制在继承构造函数中重复基类模板参数

c++ - 带有两个(或更多)特定包(特化/重载)的可变参数函数模板