6

I have a class that I only wish clients create them one object per process. Instead of singleton, a better way (I believe) is to tell the clients to only create them in main(). So a natural enforcement is to make the constructor private and main() as a friend.

It works this way:

class A { friend int main(int, char**); A() {} };
int main(int, char **) { A a; }

But it breaks when I need to put class A in a namespace:

namepace ns { class A { friend int main(int, char**); A() {} }; }
int main(int, char **) { ns::A a; }

The problem is scoping: the compiler now thinks

friend int main 

means a function named main() in namespace ns. So the real main() becomes irrelevant.

So the question is: how to fix this? Of course I'll have to put class A in a namespace.

Ralph Zhang
  • 5,015
  • 5
  • 30
  • 40
  • 2
    Making main a friend has completely different semantics than one object per process: having main as a friend does not prevent it from creating more than one object. otoh, one object per process could well mean that object is accessible in other functions that just in main(). So what do you *really* want to accomplish? What's your class about? – Arne Mertz Jan 29 '13 at 12:20
  • 1
    Why is that a better way? – Andy Prowl Jan 29 '13 at 12:22
  • 1
    I don't think `friend` does what you think it does. – Joseph Mansfield Jan 29 '13 at 12:23
  • int main(int, char **) { ns::A a, b,c,d; } – qPCR4vir Jan 29 '13 at 12:28

2 Answers2

6

You need to declare main in the global namespace before the class definition, since friend declarations can only introduce names in the surrounding namespace:

int main(int, char**);

and qualify the name when referring to it inside the namespace:

namepace ns { class A { friend int ::main(int, char**); A() {} }; }
//                                 ^^
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
5

Use "::" to qualify something as being in the global namespace, i.e.:

friend int ::main(int argc, char** argv);
sheu
  • 5,653
  • 17
  • 32