c++ - 使用模板类特化消除代码冗余的标准方法是什么?

标签 c++ c++11 templates template-meta-programming template-specialization

我有一个模板类,它使用这样的模板递归递归地构建斐波那契数组:

#include <iostream>
#include "C++ Helpers/static_check.hpp"
using namespace std;

template <typename T>
struct valid_type : std::integral_constant<bool, std::is_integral<T>::value  > {};

template <size_t N, typename = void>
struct fibonacci {
    static const int value = fibonacci<N - 1>::value + fibonacci<N - 2>::value;
};
template <size_t N>
struct fibonacci <N, typename std::enable_if<(N < 2)>::type > {
    static const int value = 1;
};
template <size_t N, typename T = int>
struct fibonacci_array {
    static_assert(valid_type<T>::value, "invalid storage type for fibonacci sequence");
// the base case specialization should has all general case code except for the next line
    fibonacci_array<N - 1, T> generate_sequence_here;
    int value;
    fibonacci_array() : value(fibonacci<N - 1>::value) {}
    int operator [] (size_t pos) {
        return *((int*)this + pos);
    }
};

template <typename T>
struct fibonacci_array<1, T> {
    static_assert(valid_type<T>::value, "invalid storage type for fibonacci sequence");
    int value;
    fibonacci_array() : value(fibonacci<0>::value) {}
    int operator [] (size_t pos) {
        return *((int*)this + pos);
    }
};

int main () {
    const size_t n = 10;
    fibonacci_array<n, int> arr;
    for(size_t i = 0; i < n; ++i)
        cout << arr[i] << endl;
    return 0;
}

我想做的是消除基本案例特化中的代码冗余(当 N == 1 时) 注意:如果我将类成员分为私有(private)成员和公共(public)成员并使用直接继承,则效率不高,因为私有(private)成员实际上被继承但无法访问它们。 我正在考虑创建一个基类以使通用模板类和特化继承自它,但我不知道它的确切语法,如果有更好的方法会更好。谢谢!

最佳答案

如何在 N=0 处终止递归? ?在这种情况下,您可以为 fibonacci_array<1, T> 扔掉整个 body 。并替换为这个小家伙:

template <typename T>
struct fibonacci_array<0, T> 
{
};

一个陷阱是这个特化是空的,但是当你把它作为generate_sequence_here聚合到主类时,它将占用 1 个字节的空间,因为在 C++ 中每个对象都应有一个唯一的地址。这将浪费您 1 个字节的空间(并且需要更新您的 operator[] )。不过不用担心,如果您更改 fibonacci_array<N - 1, T> 的聚合,它可以很容易地解决。从它继承。这要归功于称为“空基类优化”的功能。

此外,如果您可以使用 C++14,则更喜欢使用 constexpr 构造函数来完成此任务,代码会更简洁:

template <int N, typename T = int>
struct fibonacci_array 
{
    int values[N];
    constexpr fibonacci_array() : values()
    {
        if (N > 1)
            values[1] = 1;
        for (int i = 2; i < N; ++i)
            values[i] = values[i - 1] + values[i - 2];
    }
    constexpr int operator [] (size_t pos) const
    {
        return values[pos];
    }
};

参见 demo .

另请参阅编译器如何在编译时计算它:https://godbolt.org/g/kJEFvN

关于c++ - 使用模板类特化消除代码冗余的标准方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44219247/

相关文章:

c++ - DirectX 11 中未解析的外部符号 '_D3DX10CreateFontIndirectA@12'

c++ - mmap 是否返回对齐的指针值

c++ - 如何将具有无参数构造函数的对象放置到 std::map 中?

c++ - SVML 与普通内在平方根函数之间有区别吗?

c++ - Lambda 和 std::function

c++ - 类似 Luabind 的语法(索引运算符)

javascript - 如何使用 jQuery 从 <template> 中选择元素

c++ - 模拟模板类的静态构造函数

来自模板参数的 C++ 通用模板方法名称

c++ - boost::filesystem::recursive_directory_iterator 拒绝访问 C:\Users