尺寸类型 std::array 的派生模板 class

Derived template class with std::array size type

我正在使用 C++17 并且有一个模板 class 对模板变量类型有限制。我想添加一个派生的 class,它另外接受一个 std::array 参数并模板化数组的大小。

template <typename T,
typename U = std::enable_if<std::is_same_v<T, int> || std::is_same_v<T, bool>>>
class Base {
public:
    Base(T param1) : value(param1) {}

    T value;
};


template <typename T,
typename U = std::enable_if<std::is_same_v<T, int> || std::is_same_v<T, bool>>,
typename N = unsigned int>
class Derived : public Base<T, U>
{
public:
    Derived(T param1, std::array<std::pair<T, bool>, N>&& param2) :
        Base(param1),
        arr(std::move(param2)) {}

    std::array<std::pair<T, bool>, N> arr;
};

// We can use Base as such
Base<int> b { 23 };
// I want to use Derived in such a way
Derived<int, 2> d {0, {{1, true}, {2, false}} };

但是,我无法构建或创建派生 class 的实例。感谢您的帮助!

编辑: 添加了通过切换变量和取消模板化 N 提供的建议。 这是一个 MRE https://godbolt.org/z/MGj5YdbxP 创建派生实例时出现新错误。

编辑2: 我知道 sfinae 并且会解决这个问题。有没有办法让它为 r-val 参考工作,以便我可以移动第二个参数? https://godbolt.org/z/YxYssKPn3 假设我也支持将被销毁的 T 的大型 std::string 类型。

只需重新排序参数,并使用非类型模板参数:

template <typename T,
          std::size_t N,
          std::enable_if_t<std::is_same_v<T, int> || std::is_same_v<T, bool>, int> = 0>
class Derived : public Base<T>
{
// ...
};

注意:typename U = std::enable_if<condition> 不启用 SFINAE。 您需要 typename U = std::enable_if_t<condition>typename U = typename std::enable_if<condition>::type。 该表格可能会被劫持(就像您对 Base<T, U> 所做的那样);更喜欢 std::enable_if_t<condition, int> = 0.

Derived(T param1, std::array<std::pair<T, bool>, N>&& param2)

此构造函数中用于 std::array 的第二个模板参数 N 在这里是 类型 (模板参数),而 std::array 需要类型为 std::size_t.

的非类型模板参数的有效参数

您似乎想在 std::size_t.

类型的非类型模板参数上参数化您的 Derived 类型

IIRC,我对你的代码做了 2 处修改:

1.from Derived(T param1, std::array<std::pair<T, bool>, N>&& param2) : Base(param1), Derived(T param1, std::array<std::pair<T, bool>, N>&& param2) : Base<T,U>(param1),

2.from template <typename T, typename U = std::enable_if<std::is_same_v<T, int> || std::is_same_v<T, bool>>, typename N = unsigned int>

template <unsigned int N ,typename T, typename U = std::enable_if<std::is_same_v<T, int> || std::is_same_v<T, bool>> >

代码如下:


#include<array>
#include<map>

template <typename T,
    typename U = std::enable_if<std::is_same_v<T, int> || std::is_same_v<T, bool>>>
    class Base {
    public:
        Base(T param1) : value(param1) {}

        T value;
};


template <unsigned int N
    ,typename T,
    typename U = std::enable_if<std::is_same_v<T, int> || std::is_same_v<T, bool>>
    >
    class Derived : public Base<T, U>
{
public:
    Derived(T param1, std::array<std::pair<T, bool>, N>&& param2) :
        Base<T,U>(param1),
        arr(std::move(param2)) {}

    std::array<std::pair<T, bool>, N> arr;
};

// We can use Base as such
Base<int> b{ 23 };

int main() {
// I want to use Derived in such a way
    Derived<2, int> d{ 0, { std::make_pair(1, true), { 2, false } } };

    return 0;
}