混合别名和模板特化
Mixing aliases and template specializations
我正在寻找最好的方法来获得一种 "object" 可以专门化或 "linked" 到另一种类型。
例如,你不能特化一个 class 使其成为一个简单的 int,你也不能使用关键字 using 来特化 classes。
我的解决方案如下:
template<class Category, Category code>
struct AImpl
{};
template<class Category, Category code>
struct AHelper
{
using type = AImpl<Category, code>;
};
template<class Category, Category code>
using A = typename AHelper<Category, code>::type;
template<int code>
void doSomething(A<int, code> object)
{
}
template<>
struct AImpl<int, 5>
{
double a;
};
template<>
struct AImpl<int, 6>
{
int b;
double c;
};
template<>
struct AHelper<int, 7>
{
using type = int;
};
template<class Category, Category code>
struct Alternative {};
template<int code>
void doSomethingAlternative(Alternative<int, code> object)
{
}
这可行,但您需要在 doSomething 中指定代码参数,我想避免这种情况。
例如:
A<int,7> a7; // This is equivalent to int
a7 = 4;
A<int, 5> a5; // This is equivalent to AImpl<int,5>
a5.a = 33.22;
doSomething(a5); // This does not compile
doSomething<5>(a5); // This compiles but is bulky
Alternative<int,0> alt0;
doSomethingAlternative(alt0); // This compiles and is not bulky
// but you're forced to use class
// specializations only
有没有办法实现我想要的?可以同时更改 doSomething 或 A 实现。
如果您尝试根据调用它的类型自定义 doSomething
的行为,您不能让编译器从 AHelpr::type
中推导出内容(如之前的 ). But you can tell it what it needs to know by providing a customization point in the form of traits。例如:
template<typename T>
void doSomething(T& object)
{
auto code = SmthTriats<T>::code;
}
考虑到专业化的能力,这是高度可扩展的 SmthTriats
:
template<typename> struct SmthTriats;
template<typename Category, Category code_>
struct SmthTriats<AImpl<Category, code_>> {
static constexpr auto code = code_;
};
template<>
struct SmthTriats<int> {
static constexpr auto code = 7;
};
特征 class 也允许在模块外进行自定义。客户代码只需要专门化 SmthTriats
他们自己的类型,只要他们尊重你为你的特质制定的合同,你的代码就会为他们工作。
我正在寻找最好的方法来获得一种 "object" 可以专门化或 "linked" 到另一种类型。
例如,你不能特化一个 class 使其成为一个简单的 int,你也不能使用关键字 using 来特化 classes。
我的解决方案如下:
template<class Category, Category code>
struct AImpl
{};
template<class Category, Category code>
struct AHelper
{
using type = AImpl<Category, code>;
};
template<class Category, Category code>
using A = typename AHelper<Category, code>::type;
template<int code>
void doSomething(A<int, code> object)
{
}
template<>
struct AImpl<int, 5>
{
double a;
};
template<>
struct AImpl<int, 6>
{
int b;
double c;
};
template<>
struct AHelper<int, 7>
{
using type = int;
};
template<class Category, Category code>
struct Alternative {};
template<int code>
void doSomethingAlternative(Alternative<int, code> object)
{
}
这可行,但您需要在 doSomething 中指定代码参数,我想避免这种情况。
例如:
A<int,7> a7; // This is equivalent to int
a7 = 4;
A<int, 5> a5; // This is equivalent to AImpl<int,5>
a5.a = 33.22;
doSomething(a5); // This does not compile
doSomething<5>(a5); // This compiles but is bulky
Alternative<int,0> alt0;
doSomethingAlternative(alt0); // This compiles and is not bulky
// but you're forced to use class
// specializations only
有没有办法实现我想要的?可以同时更改 doSomething 或 A 实现。
如果您尝试根据调用它的类型自定义 doSomething
的行为,您不能让编译器从 AHelpr::type
中推导出内容(如之前的
template<typename T>
void doSomething(T& object)
{
auto code = SmthTriats<T>::code;
}
考虑到专业化的能力,这是高度可扩展的 SmthTriats
:
template<typename> struct SmthTriats;
template<typename Category, Category code_>
struct SmthTriats<AImpl<Category, code_>> {
static constexpr auto code = code_;
};
template<>
struct SmthTriats<int> {
static constexpr auto code = 7;
};
特征 class 也允许在模块外进行自定义。客户代码只需要专门化 SmthTriats
他们自己的类型,只要他们尊重你为你的特质制定的合同,你的代码就会为他们工作。