gpt4 book ai didi

c++ - 利用值类型和引用的统一语法

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:19:01 24 4
gpt4 key购买 nike

假设我们有以下 Base类和两个派生类 Derived1Derived2 :

class Base {
// Some declarations ...
};

class Derived1 : public Base {
// Some declarations ...
public:
vector<int> _array;
};

class Derived2 : public Base {
// Some declarations ...
public:
vector<int> &_array;
};

也就是说,我们有一个共同的类,但底层数据结构是不同类型的。

假设我们想使用来自 Base 的统一接口(interface)访问底层数组的各个元素指针。即像这样的东西:

Base *bPtr = new Derived1(...);
int val = bPtr->index(3);

有一个名为 index 的纯虚函数在 Base是一种解决方案。但是,在那种情况下,我们将需要相同的 int index(uint x) { return _array[x]; }在两个派生类中实现。这很丑陋,我们无法在 Base 中实现该功能因为它不知道 _array .

所以我们必须 (1) 改变 _array 的类型s 到相同的类型(比如,到 vector<int>* )并且有 index 的实现在 Base或 (2) 在 Derived1 中有两个实现和 Derived为了使用一个通用的接口(interface)。但是我负担不起 (1),因为它会向 Derived1 添加一个额外的间接层。 ,如果可能的话,我想避免这种情况。拥有大量这样的成员变量会使 (2) 变得可怕,因为这是大量的样板和复制,并且难以维护。

我明白这两个index函数实际上是不同的函数,因为它们对不同的类型进行操作。在许多其他场景中 Derived1Derived2将需要单独的函数,因为它们具有不同的行为(并且将被编译为不同的目标代码)。但是在 C++ 的情况下,实现在语法上是相似的,所以我想知道是否有一种方法可以利用它。

一种可能的解决方案是使用免费功能:

template <class T>
int index(const T &obj, uint x) {
return obj._array[x];
}

我们在哪里声明index两者的 friend Derived1Derived2 .但是,这可能不被认为是优雅的,因为它使用了友元声明(同时声明两次友元是重复的)。

因此,我的问题是:有没有更优雅的方式来实现 index ,同时避免性能成本和代码重复?

附录:CRTP 非常接近我想要的,但它引入了两个新类型(Base<Derived1> 是第一个,Base<Derived2> 是第二个)同时删除了现有类型 Base .这样的重构会触发代码库中的更多更改,这是不可取的(例如制作利用 Base 模板函数/类的函数/类,甚至将它们从头文件移动到源文件)。理想情况下,我想要的不需要更改代码库的其余部分。

最佳答案

使用CRTP .

template <typename D, typename B = Base>
class CrtpBase : public B
{
public:
int index(size_t ind){return static_cast<D*>(this)->_array[ind];}
};

struct Derived1 : public CrtpBase<Derived1>
{
vector<int> _array = {1,2,3};
};

struct Derived2 : public CrtpBase<Derived2>
{
vector<int> _arr = {4,5,6};
vector<int>& _array = _arr;
};

DEMO .

关于c++ - 利用值类型和引用的统一语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29269307/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com