![](/img/trans.png)
[英]How to specialize a templated member-function into a templated class in C++?
[英]How to specialize a templated class's member struct
假设我有以下模板类:
template<typename T>
class Foo {
struct store_t {
uint8_t data[];
} store;
/// other stuff using T
}
有没有办法构建一个内部结构的专用版本,等同于这样的东西:
class Foo {
struct store_t {
uint16_t f1;
uint16_t f2;
} store;
/// other stuff using T
}
我宁愿保留大部分“使用T的其他东西”非专业化。 我会专门研究一些访问者。 我觉得我想要写一些类似的东西
template<>
struct store_t {
uint16_t f1;
uint16_t f2;
} Foo<someT>::store;
但那当然不行。
与生活中的大多数事情一样,“如何通过模板解决这个问题”的答案是“使用更多模板”。
store_t
写为模板 值得庆幸的是,我们不必做任何疯狂的事情。 让我们写store_t
之外Foo
作为模板:
template<bool use_uint8>
struct Foo_store_t {
uint8_t data[];
};
template<>
struct Foo_store_t<false> {
uint16_t f1;
uint16_t f2;
};
现在,在编写Foo
,我们可以通过测试某些条件来选择我们想要使用的那个:
template<class T>
class Foo {
constexpr static bool use_uint8 = /* stuff */;
using store_t = Foo_store_t<use_uint8>;
store_t store;
};
store_t
两个版本,使用std::conditional
这个也非常简单。 std::conditional
允许您使用布尔值在两个不同(任意)类型之间进行选择。
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>;
};
这里我使用的是std::conditional_t
,它出现在C ++ 14中,但是如果你只能使用C ++ 11,那就做:
class Foo {
constexpr static bool useVersionA = /* stuff */;
using store_t = typename std::conditional<useVersionA, store_A, store_B>::type;
};
为了好玩,我展示了一种基于某种自我继承的可能解决方案。
假设你想为bool
类型使用specialize Foo
。
您可以编写主Foo
添加一个带有默认值的模板非类型参数(比如一个默认值为true
的bool
)
template <typename T, bool = true>
struct Foo
{
struct store_t
{ std::uint8_t data[10]; } store;
/// other stuff using T
T value;
};
我添加了T value
作为“使用T的其他东西”的例子。
现在,你可以专注Foo<bool>
继承Foo<bool, false>
template <>
struct Foo<bool> : public Foo<bool, false>
{
struct store_t
{ std::uint16_t f1, f2; } store;
};
这样你就可以专门化store_t
/ store
(以及其他成员,如果你愿意的话)继承自Foo<bool, false>
“使用T的其他东西”( bool value
,例如)。
以下是完整的编译示例
#include <cstdint>
#include <type_traits>
template <typename T, bool = true>
struct Foo
{
struct store_t
{ std::uint8_t data[10]; } store;
T value;
};
template <>
struct Foo<bool> : public Foo<bool, false>
{
struct store_t
{ std::uint16_t f1, f2; } store;
// inherits a bool value from Foo<bool, false>
};
int main()
{
Foo<int> fi;
Foo<bool> fb;
static_assert( std::is_same<decltype(fi.value),
int>::value, "!");
static_assert( std::is_same<decltype(fi.store.data),
std::uint8_t[10]>::value, "!");
static_assert( std::is_same<decltype(fb.value),
bool>::value, "!");
static_assert( std::is_same<decltype(fb.store.f2),
std::uint16_t>::value, "!");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.