c++ - C++ 11中的合取类型特征

标签 c++ c++11 variadic-templates sfinae

我需要检查std::enable_if中的可变参数:
使用C++ 17我会写:

template <typename A, typename ...B>
class Foo : public A, public B...
{

public:

    template <typename = std::enable_if_t<std::is_default_constructible_v<A> &&
        (std::is_default_constructible_v<B> && ...)>>
    Foo()
    {}
    
    Foo(A &&a, B && ... b)
       : A(std::forward<A>(a)),
       B(std::forward<B>(b))...
    {}

};
但是C++ 11没有以这种方式扩展参数包的功能。它也不提供std::conjunction
与C++ 11结合实现的简单方法是什么?
我想带有递归的SFINAE就足够了,但是我无法将手缠在它上面。

最佳答案

您需要一个工具来对可变参数进行合取运算。

#include <iostream>
#include <type_traits>

template<class...> struct conjunction : std::true_type { };
template<class B1> struct conjunction<B1> : B1 { };
template<class B1, class... Bn>
struct conjunction<B1, Bn...> 
    : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};

template <typename A, typename ...B>
class Foo : public A, public B...
{

public:

    template <typename std::enable_if<std::is_default_constructible<A>::value &&
        conjunction<std::is_default_constructible<B>...>::value, bool>::type = true>
    Foo()
    {}
    
    Foo(A &&a, B && ... b)
       : A(std::forward<A>(a)),
       B(std::forward<B>(b))...
    {}

};

struct A {};
struct B {};
struct C {
    C(int x) {}
};

int main()
{
    Foo<A, B> foo;
    //Foo<A, B, C> bar;

    return 0;
}
https://godbolt.org/z/d3jvM4
基于C++ 17中可用的https://en.cppreference.com/w/cpp/types/conjunction

关于c++ - C++ 11中的合取类型特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63229532/

相关文章:

c++ - Visual Studio C 编译器或 Intel Intrinsics 的 AVX2 "_mm256_set_epi64x"函数中的潜在错误

C++ 删除包含新结构数组的新结构数组的正确方法?

c++ - 可变参数模板的模板特化

c++ - 从模板生成的重复类型

c++ - 函数返回的 decltype

c++ - 使用返回类型调用模板化成员指针函数时出错

c++ - 使用从 Solaris 64 位或 Linux 32 位到 Linux 64 位的内存映射文件

c++ - 如何正确传递 C/C++ *(PUCHAR)(..)?

c++ - 初始化和 lambda 类型参数

C++11 unordered_map 时间复杂度