我可以在引用返回类型中返回指针吗



我正在编写一个模板化的类,我有这样的东西:

template<class T> class ... {
    T x, y, z;
    T& operator[](int index) {
        switch (index) {
            case 0:
                return this->x;
                break;
            case 1:
                return this->y;
                break;
            case 2:
                return this->z;
                break;
        }
    }
}

我已经考虑过用这个来改变它:

T& operator[](int index) { return *(&this->x + index); }

然而,我在原始代码中返回的是实际变量(也称为引用),它执行它想要的操作(myObj[1] = 123; /*changes the actual object*/),而在第二个示例中,我返回该指针的值。

我可以更改为return (&this->x + index)来返回指针,但这两种情况都是编译的(Visual Studio 2013),我不知道该选择哪一种,因为我从未做过这样的事情。

那么,问题是:有没有什么方法可以使用指针算术来动态返回正确的变量,或者我需要切换?

指针算术方法会导致未定义的行为。例如,编译器可能会在这三个变量之间添加填充,这会使指针算术方法出现故障。它可能适用于某些类型的T,而可能适用于另一种类型。

您要么需要使用切换方法,要么将您的成员从T x, y, z;更改为T coords[3];,这样您就可以使用具有定义和正确行为的索引方法。

关于您问题的主题,是的,将指针引用转换为引用通常是安全的。您将返回指向对象的引用。在这种情况下,它不是一个好方法的唯一原因是指针算术本身会导致未定义的行为。

所以,问题是:有什么方法可以使用指针算术来动态返回正确的变量,还是我需要切换?

实际上,你的指针运算会当场引发未定义的行为,因为添加了一些>1指向不指向数组对象的指针会导致未定义的行为,[expr.add]:

  1. 对于这些运算符,指向非数组对象的指针行为与指向的数组的第一个元素的指针相同length一,将对象的类型作为其元素类型。

  2. 当对具有整型的表达式进行加法运算或减法运算时从指针中,结果具有指针操作数的类型。[…]
    如果指针操作数和结果都指向相同的元素数组对象,或数组对象最后一个元素之后的一个评估不得产生溢出;否则,行为为未定义。

您可以使用数组,并通过索引访问变量。请注意,switch语句应该生成一个跳转表,不使用任何分支,甚至可能经过优化以生成与指针算法相同的代码。

尽管如此,如果您想向外部提供数组语义,您可能应该在内部保留一个数组。

除非x, y, z保存在同一个容器中,否则我强烈避免执行第二个示例中的操作。即使从维护的角度来看,如果有人来了,决定重新安排你的成员或添加一个新成员(例如,在xy之间),那么你的神奇记忆访问就完全混乱了。此外,如果使用3作为参数调用函数,该怎么办?现在,你可以保证指向你不想指向的内存。

为了清晰、记忆安全和可持续性,请使用switch语句。此外,在return之后,您不需要break。。。这是个禁忌。最后,如果用户指定了负数或大于2的数字,则需要默认行为。抛出异常或以其他方式指示错误情况。

最新更新