Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 确保可变模板不包含重复项_C++_Templates_C++11_Variadic Templates - Fatal编程技术网

C++ 确保可变模板不包含重复项

C++ 确保可变模板不包含重复项,c++,templates,c++11,variadic-templates,C++,Templates,C++11,Variadic Templates,我想我的整个问题在标题中都描述得很好。我正在尝试创建一个可变类模板(在C++11、C++14或C++1z中) 它不会编译(我很乐意使用static\u assert以某种方式进行编译) 请给我一个提示。这可以在两个元函数的帮助下编写 首先,IsContained检查类型是否出现在类型列表中 template <typename T, typename... List> struct IsContained; template <typename T, typename Hea

我想我的整个问题在标题中都描述得很好。我正在尝试创建一个可变类模板(在C++11、C++14或C++1z中)

它不会编译(我很乐意使用
static\u assert
以某种方式进行编译)


请给我一个提示。

这可以在两个元函数的帮助下编写

首先,
IsContained
检查类型是否出现在类型列表中

template <typename T, typename... List>
struct IsContained;

template <typename T, typename Head, typename... Tail>
struct IsContained<T, Head, Tail...>
{
    enum { value = std::is_same<T, Head>::value || IsContained<T, Tail...>::value };
};

template <typename T>
struct IsContained<T>
{
    enum { value = false };
};
使用这些工具,静态断言非常简单:

template <typename... Ts>
struct NoDuplicates
{
    static_assert(IsUnique<Ts...>::value, "No duplicate types allowed");
};
模板
结构节点重复
{
静态_断言(IsUnique::value,“不允许重复类型”);
};

如果您可以访问C++1z折叠表达式,您可以通过对包含的
执行以下操作来简化@TheOperator的答案:

template <typename T, typename... List>
struct IsContained;

template <typename T, typename Head, typename... Tail>
struct IsContained<T, Head, Tail...>
{
    enum { value = std::is_same<T, Head>::value || (IsContained<T, Tail>::value && ... && true) };
};

template <typename T>
struct IsContained<T>
{
    enum { value = false };
};
模板
结构是包含的;
模板
结构是包含的
{
枚举{value=std::is_same::value | |(IsContained::value&&…&&true)};
};
模板
结构是包含的
{
枚举{value=false};
};

不同之处在于,使用fold表达式时,重用类实例化的可能性更大。如果使用了大量参数或多次重复比较,则编译时间可能会更快。像往常一样,自己测试一下。

使用c++17,这非常简单

#include <type_traits>

template <typename T, typename... Ts>
struct are_distinct: std::conjunction<
    std::negation<std::is_same<T, Ts>>...,
    are_distinct<Ts...>
>{};

template <typename T>
struct are_distinct<T>: std::true_type{};
#包括
模板
结构是不同的:std::conjunction<
否定。。。,
你与众不同吗
>{};
模板
结构是不同的:std::true\u类型{};
该算法与和所示的算法相同,但表达更加简洁

然后,谈到您的具体问题,您可以这样使用它:

template<typename ...Types> 
struct MyVariadicTemplate {
    static_assert(are_distinct<Types...>::value, "Types must be distinct");

    /* rest of the code */
};
模板
结构MyVariadicTemplate{
静态_断言(are_distinct::value,“类型必须是不同的”);
/*代码的其余部分*/
};

然而,考虑到这是O(n²),我想知道是否有一种方法可以使它在算法上不那么复杂,但我无法理解它使用的算法。

哇,这太聪明了。我刚刚看到了阶乘的例子,但我没有想到要应用它。它在我以后的工作中也很有用,因为我无论如何都需要被包容。谢谢我喜欢用
enum{value=…}
代替
static constexpr auto value=…
谢谢。出于好奇-是否有必要在折叠表达式的末尾添加(&&true)?这里提到,如果有一个空包,折叠和计算结果为true。@Jytug在最近的标准化会议上,他们删除了一元折叠的所有默认值,并使一元折叠的空包格式不正确(请参见P0160R0)。这就是为什么我做了二进制折叠(使用&&true)(IsContained::value&&&…&&true)这是不正确的!而是使用(IsContained::value | | |…| | | false),因为如果任何IsContained::value为true,则折叠表达式结果应该为true。
template <typename T, typename... List>
struct IsContained;

template <typename T, typename Head, typename... Tail>
struct IsContained<T, Head, Tail...>
{
    enum { value = std::is_same<T, Head>::value || (IsContained<T, Tail>::value && ... && true) };
};

template <typename T>
struct IsContained<T>
{
    enum { value = false };
};
#include <type_traits>

template <typename T, typename... Ts>
struct are_distinct: std::conjunction<
    std::negation<std::is_same<T, Ts>>...,
    are_distinct<Ts...>
>{};

template <typename T>
struct are_distinct<T>: std::true_type{};
template<typename ...Types> 
struct MyVariadicTemplate {
    static_assert(are_distinct<Types...>::value, "Types must be distinct");

    /* rest of the code */
};