如何禁止对不引用变量进行赋值?

3

我知道这可能是个愚蠢的问题,但是...

有人能给我提供一种方法,强制函数(或方法)返回对内部静态变量或类/结构体成员的引用,只能分配给引用变量吗?

我尝试用一个简单的例子来解释我的需求。

考虑以下代码,其中有一个名为wrapValue()的函数,它返回对内部静态变量的引用:

int & wrapValue (int v0)
 {
   static int val;

   return val = v0;
 }

int main ()
 {
   // how to permit this ...
   int & v0 { wrapValue(0) };

   // ... but forbid this ...
   int   v1 { wrapValue(1) };

   int   v2;

   // ... and this ?
   v2 = wrapValue(2);
 }

有一种方法可以允许初始化v0(并将v0绑定到静态变量),禁止初始化v1和赋值v2(而不绑定v1v2到静态变量)吗?
如果在当前的C++标准下无法实现,有人可以建议我另一种方式(但不要太复杂:我打算在一个希望保持简单的库中使用它)来禁止未绑定的赋值吗?

为什么你要这样做?你的返回值不是由调用者决定怎么处理吗? - Alan Stokes
也许您不希望复制该值,只需移动和构造?或者甚至不需要移动? - wally
@AlanStokes - 问题在于,如果用户将我开发的方法返回的值(从argc/argv值解析的选项类)放入简单(非引用)值中,则会丢失下一个要解析的值。也许这是个愚蠢的想法,但似乎运行良好,如果用户记得使用&。我的英语不好,所以很难解释...如果您有兴趣(根据Stack Overflow规则,这是正确的吗?),我可以写下我的github项目链接。 - max66
@flatmouse - 我的真正问题更加复杂,涉及到模板和虚方法;简而言之,我想保存一个变量的引用,该变量是在调用方法时创建的类实例内部的内部变量;如果用户忘记了 &,则引用将丢失,并且在后续阶段设置的值也将丢失;也许我的解决方案很愚蠢,但如果用户记得 &,它似乎是有效的。 - max66
2个回答

4

这个解决方案有点棘手,但它可以按照您的期望工作(我认为):

#include <iostream>

struct int_wrapper {
    int value;
    int_wrapper &operator=(int value) {
        this->value = value;
        return *this;
    }
    operator int&() {
        return value;
    }
    operator int() {
        return value;
    }
};

int_wrapper& wrapValue (int v0) {
   static int_wrapper val;
   return val = v0;
}

int main () {
   // how to permit this ...
   int & v0 = wrapValue(0);

   // ... but forbid this ...
   //int   v1 { wrapValue(1) }; // call ambigious

   int   v2;
   (void)v0;
   (void)v2;

   // ... and this ?
   //v2 = wrapValue(2); // call ambigious
}

[live demo]


棘手但易于使用和美观。我的真正问题涉及模板,但应该很容易修改您的int_wrapper在模板包装器中。我会尝试,但是...暂时+1。 - max66
@max66 我不确定为什么,但这个解决方案不允许使用花括号初始化引用,例如 int &v0{wrapValue(0)};(类似于值的歧义?)。另一方面,int &v0(wrapValue(0)); 不会导致歧义... 不知道如何解释这个问题... - W.F.
有趣;我也是(我不知道如何解释这个...);我想你应该开一个问题 :) - max66
done - W.F.

2
据我所知,int类型是可复制的,所以人们可以自由复制;您无法阻止这种情况的发生。但是,您可以创建一个包装类来实现不可复制性。
class NonCopyableInt
{
    int val;
public:
    NonCopyableInt(int val) : val(val) {}
    NonCopyableInt(NonCopyableInt&) = delete;
    int& value() { return val; }
    // todo: add some nice operators and functions such as assignment from int
}

NonCopyableInt& wrapValue (int v0)
{
    static NonCopyableInt val;
    return val = v0;
}

然而,人们总是可以从value()中复制返回值,因此你最终会遇到同样的问题。而且这种方式感觉非常笨拙和不好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接