C++在编译时在两个变量之间交替

标签 c++ arrays vector c++17

假设您有一个对 vector 进行操作的类:

class Foo{
public:
    Foo() {
        m_dynamic_data.push_back(5);
        std::cout << m_dynamic_data[0] << std::endl;
    }
private:
    std::vector<int> m_dynamic_data;
};

在我的例子中,这个类非常庞大,有 2500 行额外的代码。 此类行为动态(因此 std::vector)。但我也想提供一个“静态”实现(使用 std::array)。所以添加了 std::size_t N,它现在应该控制何时使用哪个属性。

template<std::size_t N>
class Foo{
private:
    std::vector<int> m_dynamic_data;  //use this, when N == 0
    std::array<int, N> m_static_data; //use this, when N != 0
};

我不确定我是否可以让它工作。使用 #define 不会完成这项工作(因为它不能交替)。 constexpr 也不能包含两个属性。最好的解决方案可能是提供一个基类,然后从中继承动态和静态案例。但是在我接下来的几天做这件事之前,我想知道到底是不是没有技巧。

我考虑过将两者都放入 std::unique_ptr 并只构建相关数组:

template<std::size_t N>
class Foo {
public:
    Foo() {
        if constexpr (N) {
            m_static_data_ptr = std::make_unique<std::array<int, N>>();
            (*m_static_data_ptr)[0] = 5;
            std::cout << (*m_static_data_ptr)[0] << std::endl;
        }
        else {
            m_dynamic_data_ptr = std::make_unique<std::vector<int>>(1);
            (*m_dynamic_data_ptr)[0] = 5;
            std::cout << (*m_dynamic_data_ptr)[0] << std::endl;
        }
    }
private:
    std::unique_ptr<std::vector<int>> m_dynamic_data_ptr;
    std::unique_ptr<std::array<int, N>> m_static_data_ptr;
};

我之前问过这个案例here .但显然这似乎不是一个好方法。 (内存碎片,高速缓存未命中率)。 std::optional 看起来也很有趣,但它使 sizeof(Foo) 超出了我的目标。

最终还有使用void指针:

template<std::size_t N>
class Foo {
public:
    Foo() {
        if constexpr (N) {
            m_data = malloc(sizeof(std::array<int, N>));
            (*static_cast<std::array<int, N>*>(m_data))[0] = 5;
            std::cout << (*static_cast<std::array<int, N>*>(m_data))[0] << std::endl;
        }
        else {
            m_data = new std::vector<int>;
            (*static_cast<std::vector<int>*>(m_data)).push_back(5);
            std::cout << (*static_cast<std::vector<int>*>(m_data))[0] << std::endl;
        }
    }

    ~Foo() {
        delete[] m_data;
    }
private:
    void* m_data;
};

但这看起来很脏 [...] 所以目标是在编译时使用任一数组结构。感谢您的帮助/建议!

最佳答案

您可以将Foodata 部分抽象为另一个类模板。

template<std::size_t N> struct FooData
{
   std::array<int, N> container;
}

template <> struct FooData<0>
{
   std::vector<int> container;
}

template<std::size_t N>
class Foo{
   private:
      using DataType = FooData<N>;
      DataType data;
};

您必须向 FooData 添加成员函数以支持额外的抽象。此类函数的数量及其接口(interface)取决于您对 Foo 中容器的使用方式有何不同。

关于C++在编译时在两个变量之间交替,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51885516/

相关文章:

c++ - 修改 std::vector 的底层数据结构不会改变它的大小

c++ - 我需要取消分配 vector 中的对象指针吗?

c++ - 如何构建有或没有递归的非二叉树?

c++ - cmake 和 make 不会创建文件夹并将文件复制到其中

c++ - 未知原因的编译器错误 (C++)

php - 查找数组中的最大值

c++ - 如何找到 vector 中的最大元素 (C++)?

c++ - 对于看起来非常好的 C++ 代码,VC++ 中的错误?

c - 如何将 char* 复制到 char[][]

python - 使用 numpy 平铺二维数组