C ++在编译时在两个变量之间交替 [英] C++ Alternating between two variables at compile time

查看:90
本文介绍了C ++在编译时在两个变量之间交替的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您有一个对向量进行运算的类:

Suppose you have a class that operates on a 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 ,它现在应该控制何时使用哪个属性。

In my case this class is huge with 2500 additional lines of code. This class behaves dynamic (hence std::vector). But I would also like to provide a "static" implementation (using std::array). So std::size_t N is added, which now should control when to use which attribute.

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 也不能包装在两个属性中。最好的解决方案可能是提供一个基类,然后从中继承动态和静态的情况。但是在我接下来的几天里这样做之前,我想知道是否还没有一种技术。

I am not sure if I can get this to work. using #define won't do the job (since it can't alternate). constexpr can't be wrapped around two attributes either. The best solution is probably to provide a base class and then inherit the dynamic and static case from it. But before I spent the next days doing this, I wonder if there isn't a technique afterall.

我考虑过将两者都放入 std :: unique_ptr 并仅构造相关的数组:

I thought about putting both into a std::unique_ptr and only constructing the relevant array:

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;
};

我早些时候问过这种情况此处。但这显然不是一个好方法。 (碎片内存,缓存未命中率)。 std :: optional 似乎也很有趣,但是它使sizeof(Foo)超出了我的目标。

I earlier asked about this case here. But apparently this doesn't seem like a good approach. (fragmenting memory, cache miss rate). std::optional also seems interesting, but it pushes the sizeof(Foo) too far for my goal.

最终,还会使用 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;
};

但这似乎很脏[...]
所以目标是工作在编译时使用任一数组结构。谢谢您的任何帮助/建议!

But this seems pretty dirty [...] So the goal would be to work with either array structure at compile time. Thanks for any help / suggestion!

推荐答案

R Sahu的答案很好,但是您不需要通过以下方式间接访问容器一个结构。

R Sahu's answer is great, but you don't need to access the container indirectly through a struct.

template<std::size_t N>
struct FooData { using type = std::array<int, N>;};

template <>
struct FooData<0> { using type = std::vector<int>; };

template<std::size_t N>
using FooData_t = typename FooData<N>::type;

template<std::size_t N>
class Foo{
   private:
      FooData_t<N> data;
};

或者,您也可以使用 std :: conditional_t

template<std::size_t N>
class Foo{
   private:
      std::conditional_t<N==0, std::vector<int>, std::array<int, N>> data;
};

这篇关于C ++在编译时在两个变量之间交替的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆