0

Imagine that we have a non-temporary int value which is referenced by an instance of another class Foo:

class Foo
{
public:
  Foo(const int& reference) : 
      mReference(reference)
  {
  }

private:
   const int& mReference;
};

Instances of Foo should reference this int value but not copy it.

Is it possible to somehow define the constructor argument to avoid a possible accidental copying?

class Foo
{
public:
  Foo(const int& reference) : 
      mReference(reference) // We need to somehow prevent this copying
  {
  }

private:
   // The member is accidentally defined not as const int& but as int
   int mReference;
};

Is it any std-way to do this, something like std::unique_ptr but for references and without dynamic memory allocation?

Dmitry Sapelnikov
  • 1,129
  • 8
  • 16
  • Not really, I think: if you have something that can initialize `const int&`, the same something can also initialize `int`. – yeputons Mar 21 '23 at 20:44
  • i do not understand the question. Your first version is fine. In the second the member is not a reference but an `int`, ie the only way to initalize it is a copy – 463035818_is_not_an_ai Mar 21 '23 at 20:44
  • 1
    if you wrap the `int` into a custom type that cannot be copied then it cannot be copied. – 463035818_is_not_an_ai Mar 21 '23 at 20:46
  • For example, when when we define an argument as a constant reference, we guarantee that a value passed to the argument won't be modified. I need to guarantee that the value passed to the argument won't be copied. – Dmitry Sapelnikov Mar 21 '23 at 20:49
  • Yes, @463035818_is_not_a_number it is clear that I need a wrapper over int. But I'm looking for a wrapper provided by a standard library that doesn't allocate dynamic memory unlike std::unique_ptr – Dmitry Sapelnikov Mar 21 '23 at 20:51
  • why do you need to prevent an `int` from being copied? This looks like a [xy problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). What is the actual problem you are trying to solve? – 463035818_is_not_an_ai Mar 21 '23 at 20:51
  • @DmitrySapelnikov there is no standard wrapper to prevent copying a reference. You will have to write your own. – Remy Lebeau Mar 21 '23 at 20:54
  • @463035818_is_not_a_number well, of course it is not about passing a simple int. I'd like to explicitly forbid copying of a class instance passed to a constructor of another class to avoid possible typos. – Dmitry Sapelnikov Mar 21 '23 at 20:54
  • Of course? We can only know what you tell us. Preventing to copy an `int` is highly questionable. Preventing to copy a custom type is something rather common. – 463035818_is_not_an_ai Mar 21 '23 at 20:56
  • 1
    Why don't you just delete the copy constructor of your class? And possibly to make it copyable again give it an explicit `copy` or `clone` method. – chrysante Mar 21 '23 at 21:04

1 Answers1

1

I am not sure if I understand what you are trying to achieve, but if you wrap the integer in a non-copyable class then this will fail to compile:

struct Foo {
  Foo(const non_copyable_int& m) :  m(m)
  {}
   non_copyable_int m;
};

Noncopyable can look like this:

struct non_copyable_int {
     int value;
     explicit non_copyable(int value) : value(value) {} // should be explicit! 
     non_copyable(const non_copable&) = delete;
     non_copyable& operator=(const non_copyable&) = delete;
};

Note that there is boost::non_copyable. I don't expect it to come in std too soon. Here you can find some arguments against its use https://stackoverflow.com/a/7841332/4117728, in a nutshell: explicitly declaring the special members can be considered more clear than putting it in a base class. Also note that boost::non_copyable is from a time when it was not that straight-forward, simple and clear to delete the special members.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • I wrote pretty similar thing. I was just wondering if it was an std-powered way to do this. – Dmitry Sapelnikov Mar 21 '23 at 20:58
  • @DmitrySapelnikov no there isnt. See edit I just added. It exists in boost but not in std. – 463035818_is_not_an_ai Mar 21 '23 at 20:59
  • @DmitrySapelnikov when its "language-powered" why look for something else? – 463035818_is_not_an_ai Mar 21 '23 at 21:02
  • boost::non_copyable is a mixin class. It is used as a base class for classes that should be never copied. In my case the referenced class cannot be made non-copyable. – Dmitry Sapelnikov Mar 21 '23 at 21:03
  • 1
    @DmitrySapelnikov yes....and? You need to copy the `int` to get it into the wrapper. Else you are back at square one: How would you make sure the `int` is not copied when placed in the wrapper. – 463035818_is_not_an_ai Mar 21 '23 at 21:04
  • @DmitrySapelnikov " the referenced class cannot be made non-copyable" then your requirements are contradicting. YOu want to make something non-copyable that cannot be made non-copyable – 463035818_is_not_an_ai Mar 21 '23 at 21:05
  • @DmitrySapelnikov You need to tell us about the actual issue. Preventing to copy an `int` is not your problem, what the problem is you need to solve is yet unclear. – 463035818_is_not_an_ai Mar 21 '23 at 21:06
  • good point. But in my case this reference-but-not copy pattern should be applied to a bunch of classes referencing values. With a proper wrapper I'll have only one point in code prone to a mistake. – Dmitry Sapelnikov Mar 21 '23 at 21:07
  • @DmitrySapelnikov sorry I do not understand what you are talking about. Its a [xy problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). You have some problem you want to get solved, you thought that if you just know how to prevent an `int` from being copied that will also solve your initial problem, but it seems like not. I suggest you to open a new question to ask about the actual problem, because this one is about not copying an `int`, not about "a bunch of classes" – 463035818_is_not_an_ai Mar 21 '23 at 21:09
  • maybe I've oversimplified my issue in the question. In reality I have a list of 3-d transformations. These transformations are referenced by around 10 visualization classes. Once I did the mistake described, and instances of the corresponding class didn't have proper update of their transformations in the rendering cycle. I was easy to fix the typo, but I started wondering if it is a general way to avoid such kind of mistakes. – Dmitry Sapelnikov Mar 21 '23 at 21:12