18

I want to do the opposite of making instances of a class noncopyable, that is, make sure that instances of a particular class can be passed only as a copy and not as a reference. If any function tries to receive it by reference, I would like it to give a compilation error (ideally) or a run time error.

I dont think making operator & private is going to do it, is there a legitimate way of doing this.

san
  • 4,144
  • 6
  • 32
  • 50
  • 2
    Fair question but chances are if you want to do this it's indicative of bad design. This will prohibit you from factoring a large function if this object is used throughout. – djechlin Nov 05 '12 at 16:19
  • 1
    Interesting idea, but this would basically be the same as disallowing a pointer to that kind of object, and that seems pretty unreasonable to me. – Dan F Nov 05 '12 at 16:19
  • @DanF disallowing pointers would I think be easier. Making `&` private should do it. – san Nov 05 '12 at 16:21
  • @djechlin Could you substantiate your claim ? I can think of one use case, auto/scoped pointers. Passing them by reference subverts there intent. – san Nov 05 '12 at 16:25
  • 1
    @san - not at all, I often do something like `Type& t = *pointerToType;` to avoid juggling pointer dereferences. That only subverts the intent if the function it's passed to plans to take ownership which for many many functions will not be the case. – djechlin Nov 05 '12 at 16:39
  • 2
    @san - Interestingly enough, C++11 provides a `std::addressof` function that provides the address of an object even if you override or hide the `&` operator. – Bo Persson Nov 05 '12 at 16:50
  • @djechlin Correct me if I am wrong, but one of the intended semantics of (a non const) auto_ptr is that if I pass it to some function it is the functions responsibility from then on. Anything that allows a function to deny responsibilty is a subversion of intent (especially when my code calls third party libraries when deployed on the client side). If every function was ideal, careful and well behaved, well, we wouldnt even need auto_ptrs to begin with, is it not ? – san Nov 05 '12 at 16:57
  • @BoPersson upvoted for the information, thanks – san Nov 05 '12 at 16:57
  • 2
    For a specific object you can prevent taking the address of a variable by declaring the variable as `register`. I.e. `register int a; &a;` is not allowed. But this won't help with what is being asked for here. – amaurea Nov 05 '12 at 18:32
  • @amaurea Thanks. I never knew. – san Nov 06 '12 at 22:29

2 Answers2

22

That's impossible. Any named variable can bind to a reference variable of the appropriate type. That's just how the language works.

In particular, you could never have a copy constructor with your restriction, so you couldn't actually pass the object by value!

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
7

I dont think making operator & private is going to do it, is there a legitimate way of doing this.

No, because the & you use in function signatures for pass-by-reference is not an operator. You're talking either about the address-of operator (unary) or bitwise-and operator (binary). So it has nothing to do with pass-by-reference.

There's no way to disallow pass-by-reference for a type.

I doubt your motivation is strong enough to do this, and you appear to have a bad understanding of the passing mechanism:

If any function tries to receive it by reference, I would like it to give a compilation error (ideally) or a run time error.

A function either passes a parameter by reference, or by value. It's decided by its declaration, and I think your confusion stems from here. For example:

void foo(X x);

takes the parameter x by value. There's no way to pass it by reference. No way. Likewise:

void foo(X& x)

takes it by reference, and it always will.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625