类模板,独立于其参数的排列
Class template, which is independent of the permutations of its arguments
考虑一个类模板和辅助枚举类,定义如下:
enum class Color {Red, Green, Blue}
enum class ShowAxes {False, True}
enum class ShowLabels {False, True}
template< Color, ShowAxes, ShowLabels >
class A
{......};
问题是,如何重新定义A类,它将独立于其参数的排列。我使用支持 C++11 的开发C++。
[编辑]
例如,新版本的 A 应该支持
A< Color::Red, ShowAxes::True, ShowLabels::True >
A< Color::Red, ShowLabels::True, ShowAxes::True >
A< ShowAxes::True, Color::Red, ShowLabels::True >
A< ShowLabels::True, Color::Red, ShowAxes::True >
A< ShowLabels::True, Color::Red, ShowAxes::True >
A< ShowAxes::True, Color::Red, ShowLabels::True >
版本,并且它们都是相同的,即它们生成相同的类。
使用非类型参数的当前接口是不可能的。
您可以改用类型参数并将值包装在std::integral_constant
中:
template<class X, class Y, class Z>
class A { /* stuff */ };
// use as:
A<std::integral_constant<Color, Color::Red>,
std::integral_constant<ShowAxes, ShowAxes::True>,
std::integral_constant<ShowLabels, ShowLabels::True>> a;
这是相当冗长的,所以你可以考虑编写一个宏:
#define AS_IC(Value) std::integral_constant<decltype(Value), Value>
并重写为
A<AS_IC(Color::Red), AS_IC(ShowAxes::True), AS_IC(ShowLabels::True)> a;
从 integral_constant
s 列表中提取所需类型的值非常简单:
template<class Result, class...>
struct extract;
template<class Result, Result Value, class... Tail>
struct extract<Result, std::integral_constant<Result, Value>, Tail...> : std::integral_constant<Result, Value> {};
template<class Result, class Head, class... Tail>
struct extract<Result, Head, Tail...> : extract<Result, Tail...> {};
然后你可以做
// inside the definition of A
static constexpr Color col = extract<Color, X, Y, Z>::value;
演示。
但是,这不会生成相同的类,但您可以创建一个类模板A_impl
,该模板的行为类似于使用非类型参数的A
,并且包含实际实现,然后A
创建别名模板:
template< Color, ShowAxes, ShowLabels >
class A_impl
{/* stuff */};
template<class X, class Y, class Z>
using A = A_impl<extract<Color, X, Y, Z>::value,
extract<ShowAxes, X, Y, Z>::value,
extract<ShowLabels, X, Y, Z>::value>;
现在给出
A<AS_IC(Color::Red), AS_IC(ShowAxes::True), AS_IC(ShowLabels::True)> a;
A<AS_IC(Color::Red), AS_IC(ShowLabels::True), AS_IC(ShowAxes::True)> b;
a
和b
具有相同的类型。演示。
或者,您也可以使用decltype
和重载函数模板,但这需要为每个可能的类型顺序添加一个函数模板声明:
template< Color c, ShowAxes a, ShowLabels l>
A<c,a,l> A_of();
template< ShowAxes a, ShowLabels l, Color c>
A<c,a,l> A_of();
// etc.
decltype(A_of<Color::Red, ShowAxes::True, ShowLabels::True>()) a1;
decltype(A_of<ShowAxes::True, ShowLabels::True, Color::Red>()) a2;
也许通过使用std::is_same。然后,您可以通过以下方式简化代码:
template <typename A, typename B, typename C>
class X
{
public:
X() {
static_assert(
std::is_same<A, Color>::value ||
std::is_same<B, Color>::value ||
std::is_same<C, Color>::value,
"nope");
// other assertions here!
// also, make sure your types are different ;)
}
X(A a, B b, C c) : X() {
// your code here
}
};
template <typename A, typename B, typename C>
X<A, B, C> make(A a, B b, C c) {
// possible verifications here
return X<A, B, C>(a, b, c);
}
int main() {
auto a = make(Color::Red, ShowAxes::true, ShowLabels::True);
return 0;
}
您可以验证所有类型 A、B 和 C。
对不起,我没有看到任何其他解决方案。
相关文章:
- 如何反转整数参数包
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 为什么不;名字在地图上是按顺序排列的吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 调用参数排列不变函数 f(i++, i++)
- 类模板,独立于其参数的排列
- 用于以任意顺序传递参数的构造函数排列
- 带有输出长度限制和特殊参数的c++排列
- 使函数接受其参数列表的任意排列的规范方法是什么?