Cho*_*rin 4 c++ templates template-specialization
说我有以下模板化的类:
template<typename T>
class Foo {
struct store_t {
uint8_t data[];
} store;
/// other stuff using T
}
Run Code Online (Sandbox Code Playgroud)
有没有一种方法可以构造内部结构的专用版本,该版本等同于以下内容:
class Foo {
struct store_t {
uint16_t f1;
uint16_t f2;
} store;
/// other stuff using T
}
Run Code Online (Sandbox Code Playgroud)
I would prefer to keep most of the "other stuff using T" unspecialized. I would specialize some accessors though. I feel I would want to write something like
template<>
struct store_t {
uint16_t f1;
uint16_t f2;
} Foo<someT>::store;
Run Code Online (Sandbox Code Playgroud)
but that of course doesn't work.
As with most things in life, the answer to "how do I solve this problem I'm having with templates" is "use more templates."
store_t as a templateThankfully, we don't have to do anything crazy. Let's write store_t outside of Foo as a template:
template<bool use_uint8>
struct Foo_store_t {
uint8_t data[];
};
template<>
struct Foo_store_t<false> {
uint16_t f1;
uint16_t f2;
};
Run Code Online (Sandbox Code Playgroud)
Now, when writing Foo, we can just pick which one we wanna use by testing some condition:
template<class T>
class Foo {
constexpr static bool use_uint8 = /* stuff */;
using store_t = Foo_store_t<use_uint8>;
store_t store;
};
Run Code Online (Sandbox Code Playgroud)
store_t, use std::conditionalThis one is also pretty straight-forward. std::conditional lets you pick between two different (arbitrary) types using a boolean.
struct store_A {
uint8_t data[];
};
struct store_B {
uint16_t f1;
uint16_t f2;
};
class Foo {
constexpr static bool useVersionA = /* stuff */;
using store_t = std::conditional_t<useVersionA, store_A, store_B>;
};
Run Code Online (Sandbox Code Playgroud)
Here I'm using std::conditional_t, which appears in C++14, but if you're restricted to using C++11 just do:
class Foo {
constexpr static bool useVersionA = /* stuff */;
using store_t = typename std::conditional<useVersionA, store_A, store_B>::type;
};
Run Code Online (Sandbox Code Playgroud)