模板参数数组
Template Parameter Array
我正在尝试创建一个 class,它使用数组的值作为 value/type 模板参数。见下文
template< std::array<bool, M> arr>
class gf {
...
};
我相信我这样做的理由是明智的。 class 为加法和乘法实现运算符重载。只有当 class 的实例使用与 arr
.
相同的值和大小实例化时,这些操作才被明确定义
一个用例示例:
std::array<bool,3> p1 = {0,0,1};
std::array<bool,3> p2 = {0,1,1};
gf<p1> a;
gf<p1> b;
gf<p2> c;
auto out1 = a + b; // works as both instances use p1
auto out1 = a + c; // Compiler error as we're adding incompatible types
我目前的解决方法是将 arr
传递给构造函数调用,并在组合任何不兼容的类型时抛出错误。我希望有更好的方法来做到这一点,谢谢!
编辑:
此外,任何其他可能实现相同目标的设计模式都将受到欢迎。我不喜欢使用模板专业化,但它是我熟悉的工具!
纯粹从技术角度来说,你可以(1)传递静态存储的constexpr
数组的地址作为非类型模板参数的持续时间:
#include <array>
template<const auto& arr>
struct gf {
gf& operator+=(const gf& /* rhs */) {
// ...
return *this;
}
};
template<const auto& arr>
auto operator+(gf<arr> lhs, const gf<arr>& rhs) {
lhs += rhs;
return lhs;
}
int main() {
// As we want to use the address of the constexpr std::array
// at compile time, it needs to have static storage duration.
static constexpr std::array<bool, 3U> p1{{0, 0, 1}};
static constexpr std::array<bool, 3U> p2{{0, 1, 1}};
gf<p1> a;
gf<p1> b;
gf<p2> c;
auto out1 = a + b; // OK.
//auto out2 = a + c; // Error: incompatible types.
}
这样 gf
class 具有唯一数组对象的模板的每个实例化都将成为唯一类型(/specialization)。
这依赖于 C++17 的 auto
作为模板参数;对于类似的 C++11 方法:
#include <array>
template<std::size_t M, const std::array<bool, M>& arr>
struct gf {
gf& operator+=(const gf& /* rhs */) {
// ...
return *this;
}
};
template<std::size_t M, const std::array<bool, M>& arr>
gf<M, arr> operator+(gf<M, arr> lhs, const gf<M, arr>& rhs) {
lhs += rhs;
return lhs;
}
int main() {
// As we want to use the address of the constexpr std::array
// at compile time, it needs to have static storage duration.
static constexpr std::array<bool, 3U> p1{{0, 0, 1}};
static constexpr std::array<bool, 3U> p2{{0, 1, 1}};
gf<3U, p1> a;
gf<3U, p1> b;
gf<3U, p2> c;
auto out1 = a + b; // OK.
//auto out2 = a + c; // Error: incompatible types.
}
(1) 这个答案不会以任何方式试图将其呈现为任何一种 good 方法来解决 XY 式问题OP.
我正在尝试创建一个 class,它使用数组的值作为 value/type 模板参数。见下文
template< std::array<bool, M> arr>
class gf {
...
};
我相信我这样做的理由是明智的。 class 为加法和乘法实现运算符重载。只有当 class 的实例使用与 arr
.
一个用例示例:
std::array<bool,3> p1 = {0,0,1};
std::array<bool,3> p2 = {0,1,1};
gf<p1> a;
gf<p1> b;
gf<p2> c;
auto out1 = a + b; // works as both instances use p1
auto out1 = a + c; // Compiler error as we're adding incompatible types
我目前的解决方法是将 arr
传递给构造函数调用,并在组合任何不兼容的类型时抛出错误。我希望有更好的方法来做到这一点,谢谢!
编辑: 此外,任何其他可能实现相同目标的设计模式都将受到欢迎。我不喜欢使用模板专业化,但它是我熟悉的工具!
纯粹从技术角度来说,你可以(1)传递静态存储的constexpr
数组的地址作为非类型模板参数的持续时间:
#include <array>
template<const auto& arr>
struct gf {
gf& operator+=(const gf& /* rhs */) {
// ...
return *this;
}
};
template<const auto& arr>
auto operator+(gf<arr> lhs, const gf<arr>& rhs) {
lhs += rhs;
return lhs;
}
int main() {
// As we want to use the address of the constexpr std::array
// at compile time, it needs to have static storage duration.
static constexpr std::array<bool, 3U> p1{{0, 0, 1}};
static constexpr std::array<bool, 3U> p2{{0, 1, 1}};
gf<p1> a;
gf<p1> b;
gf<p2> c;
auto out1 = a + b; // OK.
//auto out2 = a + c; // Error: incompatible types.
}
这样 gf
class 具有唯一数组对象的模板的每个实例化都将成为唯一类型(/specialization)。
这依赖于 C++17 的 auto
作为模板参数;对于类似的 C++11 方法:
#include <array>
template<std::size_t M, const std::array<bool, M>& arr>
struct gf {
gf& operator+=(const gf& /* rhs */) {
// ...
return *this;
}
};
template<std::size_t M, const std::array<bool, M>& arr>
gf<M, arr> operator+(gf<M, arr> lhs, const gf<M, arr>& rhs) {
lhs += rhs;
return lhs;
}
int main() {
// As we want to use the address of the constexpr std::array
// at compile time, it needs to have static storage duration.
static constexpr std::array<bool, 3U> p1{{0, 0, 1}};
static constexpr std::array<bool, 3U> p2{{0, 1, 1}};
gf<3U, p1> a;
gf<3U, p1> b;
gf<3U, p2> c;
auto out1 = a + b; // OK.
//auto out2 = a + c; // Error: incompatible types.
}
(1) 这个答案不会以任何方式试图将其呈现为任何一种 good 方法来解决 XY 式问题OP.