组类模板特化
Group class template specializations
本文关键字:类模板特化 更新时间:2023-10-16
是否存在将特定类型的类模板特化分组的技术/最佳样式?
一个例子:假设我有一个类模板Foo
,我需要对它进行同样的专门化
A = { Line, Ray }
,另一种方式是B
B = { Linestring, Curve }
到目前为止我所做的:(这里也介绍了函数的技术)
#include <iostream>
#include <type_traits>
using namespace std;
// 1st group
struct Line {};
struct Ray {};
// 2nd group
struct Curve {};
struct Linestring {};
template<typename T, typename Groupper=void>
struct Foo
{ enum { val = 0 }; };
// specialization for the 1st group
template<typename T>
struct Foo<T, typename enable_if<
is_same<T, Line>::value ||
is_same<T, Ray>::value
>::type>
{
enum { val = 1 };
};
// specialization for the 2nd group
template<typename T>
struct Foo<T, typename enable_if<
is_same<T, Curve>::value ||
is_same<T, Linestring>::value
>::type>
{
enum { val = 2 };
};
int main()
{
cout << Foo<Line>::val << endl;
cout << Foo<Curve>::val << endl;
return 0;
}
额外的辅助结构体enable_for
将缩短代码(并允许直接编写可接受的类型)。还有其他建议吗?这不应该减少工作量吗?
您也可以使用自己的特征而不使用enable_if
:
// Traits
template <class T>
struct group_number : std::integral_constant<int, 0> {};
template <>
struct group_number<Line> : std::integral_constant<int, 1> {};
template <>
struct group_number<Ray> : std::integral_constant<int, 1> {};
template <>
struct group_number<Linestring> : std::integral_constant<int, 2> {};
template <>
struct group_number<Curve> : std::integral_constant<int, 2> {};
// Foo
template <class T, int Group = group_number<T>::value>
class Foo
{
//::: whatever
};
template <class T>
class Foo<T, 1>
{
//::: whatever for group 1
};
template <class T>
class Foo<T, 2>
{
//::: whatever for group 2
};
这样做的好处是可以自动确保每种类型最多在一个组中。
通过使用两个新的类型特征来增加间接级别:
template<class T>
struct is_from_group1: std::false_type {};
template<>
struct is_from_group1<Line>: std::true_type {};
template<>
struct is_from_group1<Ray>: std::true_type {};
template<class T>
struct is_from_group2: std::false_type {};
template<>
struct is_from_group2<Curve>: std::true_type {};
template<>
struct is_from_group2<Linestring>: std::true_type {};
然后对这些类型特征做enable_if
// specialization for the 1st group
template<typename T>
struct Foo<T, typename enable_if<
is_from_group1<T>::value
>::type>
{
enum { val = 1 };
};
// specialization for the 2nd group
template<typename T>
struct Foo<T, typename enable_if<
is_from_group2<T>::value
>::type>
{
enum { val = 2 };
};
请注意,您仍然需要确保没有将用户定义的类添加到两个组中,否则会出现歧义。您可以使用@Angew的解决方案从编号为N
的编号组中获得std::integral_constant<int, N>
。或者,如果这些组在逻辑上不是互斥的,您可以在enable_if
中添加一个额外的条件来防止这种情况。
相关文章:
- 类模板实例化中的类型转换
- 类模板专用化演绎是否应该考虑演绎指南参数初始化?
- 组合多个类模板专用化
- 使用每种类型的可变参数模板上的类模板初始化元组
- C++函子的类模板专用化
- 类模板实例化错误
- 一种安全、符合标准的方法,使类模板专用化仅在实例化时才无法使用"static_assert"进行编译
- 在类模板特化中使用sizeof模板参数包
- 模板类的特化成员-不匹配-数组
- 可以创建匹配枚举类型的类模板的部分模板特化吗?
- 带有非数据类型模板参数的类模板特化
- 带有抽象基类的子类的模板特化
- 类模板特化,c++,模板形参列表中参数2不匹配
- 组类模板特化
- 模板特化中对基类成员的未定义引用
- 解析模板化类的特化静态成员变量的定义
- 模板类成员函数的模板特化
- 类的双部分模板特化
- 特征:基类的模板特化中的类型演绎
- 当模板类未特化时,成员函数的特化模板的解决方案