尺寸类型 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;
}
我正在使用 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;
}