Ale*_*xey 0 c++ sfinae template-meta-programming c++11
我想知道是否有可能编写一个模板类,在其编译版本中设置了不同的成员.
例如,如何使用继承实现它:
/// These statistics are supported for all data types
struct StatsBase {
size_t count;
virtual void Describe() { print(count); }
};
/// These can describe almost all data types, but not all of them
template<DataType data_type>
struct StatsMinMax : public StatsBase {
CppType<data_type> min;
CppType<data_type> max;
void Describe() override {
StatsBase::Describe();
print(min);
print(max);
}
};
/// These are for numeric data types only
template<DataType data_type>
struct StatsAll : public StatsMinMax<data_type> {
CppType<data_type> sum;
void Describe() override {
StatsMinMax<data_type>::Describe();
print(sum);
}
}
Run Code Online (Sandbox Code Playgroud)
并且,假设我有以下constexpr函数
constexpr bool IsMinMaxSupported(data_type dt) { /* details */ }
constexpr bool IsSumSupported(data_type dt) { /* details */ }
Run Code Online (Sandbox Code Playgroud)
所以,问题是是否有可能用C++表达这样的东西:
template<DataType data_type>
struct Stats {
size_t count;
CppType<data_type> min; // Must exist only in those instances, where IsMinMaxSupported(data_type) == true
CppType<data_type> max; // Must exist only in those instances, where IsMinMaxSupported(data_type) == true
CppType<data_type> sum; // Must exist only in those instances, where IsSumSupported(data_type) == true
void Describe() {
print(count);
if (IsMinMaxSupported(data_type)) {
print(min);
print(max);
}
if (IsSumSupported(data_type)) {
print(sum);
}
}
};
Run Code Online (Sandbox Code Playgroud)
这意味着在某些情况下某些字段必须不存在(这对于内存消耗至关重要).如果有可能,那么将Describe()按照我编写的方法编译方法,还是应该使用SFINAE重写(使用适当的专业化)?
它可以通过模板专业化来实现:
template<typename DataType, bool x_min_max_supported> struct
StatsMinMax { /* empty */ };
template<typename DataType> struct
StatsMinMax<DataType , true>
{
DataType min;
DataType max;
};
...
template<DataType data_type>
struct Stats
: public StatsMinMax<DataType, IsMinMaxSupported(data_type)>
{
Run Code Online (Sandbox Code Playgroud)