1

For some educational reason I managed to stop others from taking the address of my class objects through overloading the reference operator & as a deleted member function or as a private method. But C++11 presents a new templated-function std::addressof which returns the address of an object. So I want also to disable it, however I'm stuck in half-solution. Here is my code try:

#include "stdafx.h"
#include <memory>


class Foo {
public:
    Foo* operator&() = delete; // declared deleted so no one can take my address
    friend Foo* addressof(Foo&) = delete; // ok here.
private:
    // Foo* operator&() { return nullptr; } // Or I can declare it private which conforms to older versions of C++.

};


int main() {

    Foo f{};
//  std::cout << &f << std::endl;
//  std::cout << addressof(f) << std::endl; // ok
    std::cout << std::addressof(f) << std::endl;// Why I can't stop `std::addressof()`?

    std::cout << std::endl;
}

As you can see if I call addressof which is a friend template function to my class then it works fine. But if someone calls std::addressof on my class object the compiler doesn't prevent him.

I need some way to stop std::addressof to not be called on my objects.

Thank you guys.

Alex24
  • 600
  • 2
  • 13
  • 2
    Why do you want to prevent the address being taken? What harm does it present? – 1201ProgramAlarm Jan 26 '19 at 23:35
  • @1201ProgramAlarm: No harm in fact. But just as I said for educational purpose only. – Alex24 Jan 26 '19 at 23:36
  • You can't. Take a look at [this question](https://stackoverflow.com/questions/6494591/how-can-i-reliably-get-an-objects-address-when-operator-is-overloaded), which has a similar set up to yours but _wants_ to get the address. – 1201ProgramAlarm Jan 26 '19 at 23:44
  • 1
    Do you realize that making it possible to get an object's address even when `operator&` doesn't work is the very purpose of `addressof`? – Fabio says Reinstate Monica Jan 26 '19 at 23:47
  • 8
    I would think it's a lot more educational to show what happens when you use `operator&` on a class that overloads it and then teach `std::addressof` as a solution to the problem. – Praetorian Jan 26 '19 at 23:49
  • 1
    Note there is already a [proposal](http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2018/p1305r0.html) that deprecates the ability to overload the addressof operator. – xskxzr Jan 27 '19 at 17:11
  • @xskxzr "make due" oof – Lightness Races in Orbit Jan 28 '19 at 11:58

1 Answers1

7

No.

The whole point of std::addressof is to allow people to find the address of the object when the author has tried to make this difficult/obfuscated/awkward.

There is no way, provided by the language, to disable or inhibit it. This is a feature.

Speaking practically, you could possibly fake it by specialising std::addressof for your type if you don't mind your program having undefined behaviour as a result! (Seriously, don't do this…).

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 3
    @Deduplicator An interesting idea. But by my reading of http://eel.is/c++draft/namespace.constraints#namespace.std-2, you _can_ specialise `std::addressof`, as long as it does exactly what it would have done anyway (which in the case of `constexpr` is impossible without compiler support, which may be by the by). So you could legally do it only in a way that has no actual effect. Of course whether breaking that rule has no effect in practice is, as ever, undefined ;) For the purposes of this answer, I'm not considering possible results of UB to be "a way to disable or inhibit it" – Lightness Races in Orbit Jan 26 '19 at 23:56
  • 2
    @Deduplicator Well you "can" use a vector through an uninitialised `std::vector*`, and you "can" dereference a null pointer, and you "can" `#define std toads`, but c'mon now. I'll expand the answer a bit, with protest ;) – Lightness Races in Orbit Jan 27 '19 at 00:05
  • Thank you. I have been trying to Specialize `std::addressof` but as you know it is declared in `namespace std` consequently the compiler prevents me from specializing it outside. Could show me how to do? Thank you. – Alex24 Jan 27 '19 at 21:00
  • @Alex24 Please refer to the final sentence in the answer – Lightness Races in Orbit Jan 28 '19 at 10:42
  • I've read it all. OK. I don't do it in a real program. I managed to do it: in my source file I specialized `std::addressof` to take my `class Foo` as its generic parameter: `template<> Foo* std::addressof(Foo&){ return nullptr; }` Now if someone tries: `std::cout << std::addressof(f);`he'll get `nullptr`. Is it the way you suggested? Thank you. – Alex24 Jan 28 '19 at 11:56
  • 1
  • Thank you that was helpful especially about Undefined Behavior. – Alex24 Jan 28 '19 at 14:36
  • 1
  • You are really instructive. thanx again. – Alex24 Jan 28 '19 at 14:48