1

Is there a way to find out what the protection level of a member is?

I'm making a singleton base-class and I'd like to ensure that the child class declares its constructor/destructor as private/protected. How can I do this?

template<class c>
class singleton
{
    static_assert(std::is_private<&c::c> // does this exist?
                  || std::is_protected<&c::c>);
    static_assert(std::is_private<&c::~c>
                  || std::is_protected<&c::~c>);
};
nowi
  • 437
  • 4
  • 13
  • 1
    You can’t even refer to constructors and destructors like that. (I’m also not at all sure that this kind of tamper-proofing is a good idea in general.) – Davis Herring May 02 '20 at 02:00
  • 1
    There is nothing that a base class can do that will require its child class to do anything of that sort. This is just not possible in C++. This sounds like an XY problem. What is the ***real*** problem you're trying to solve? No, not the one about making a child class meet this requirement, but whichever the problem to which you believe the solution is to make the child class meet this requirement, so this is what you're asking about? – Sam Varshavchik May 02 '20 at 02:07
  • Will your base class work incorrectly if the derived class’s constructor or destructor is public? If not, MYOB. – Pete Becker May 02 '20 at 02:07
  • @SamVarshavchik The question mentions it, it's a singleton. – nowi May 02 '20 at 02:09
  • @PeteBecker It will not, because you'll be able to have multiple instances of the singleton. – nowi May 02 '20 at 02:09
  • 1
    [This](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4818.pdf) what you looking for (on page 26 or so. Look for `std::is_private`)? –  May 02 '20 at 02:11
  • No, having a public constructor and destructor does not mean that there **will be** more than one instance. – Pete Becker May 02 '20 at 02:11
  • @NicolBolas I'm saying it wont work because the singleton is supposed to guarantee only one instance exists. – nowi May 02 '20 at 02:11
  • @SamVarshavchik Exactly like I said, it must guarantee only one instance exists. – nowi May 02 '20 at 02:12
  • @nowi: It is not the right of a base class to enforce such a thing. To the extent that a singleton is a good idea, it's not something that needs to be encapsulated in or enforced by a base class. Basically, the question you *really* want to ask is how to make a base class that can enforce singleton status on its derived classes. And the answer is... you can't. Not at a compile-time level, at any rate. – Nicol Bolas May 02 '20 at 02:15
  • This can be done without requiring any such thing on the subclass. There are a number of approaches you can find here that count the number of instances a class gets constructed, many of them thread-safe. Implementing it in the base class's constructor, and then throwing an exception if it detects that another instance of it has already been constructed, will enforce it. – Sam Varshavchik May 02 '20 at 02:17
  • @SamVarshavchik That's stupid to me. Why count something I can prevent at compiletime? – nowi May 02 '20 at 02:19
  • @NicolBolas why is it "not the right of a base class"? Seems like arbitrary conjecture. Thanks for the opinion but C++ should have an open paradigm system for this reason. – nowi May 02 '20 at 02:22
  • @Chipster Yes, it is. – nowi May 02 '20 at 02:26
  • @nowi: "*Why count something I can prevent at compiletime?*" Why prevent making multiple instances *at all*? "*why is it "not the right of a base class"? Seems like arbitrary conjecture.*" You could say that about any language feature. Languages have *design*; languages (even C++) are not just a hodge-podge of random stuff. Subobjects are not meant to prevent their containing object from making multiple instances of itself. In fact, an object is not meant to prevent *itself* from having multiple instances made of it; you can make that happen, but only through conventions. – Nicol Bolas May 02 '20 at 02:27
  • 2
    @nowi: You can’t statically prevent multiple instances: what if the derived class offers a public factory function? As for “rights”, what you want strictly reduces the utility of the base class; while it is of course subjective, conventional wisdom is that such a restriction demands a stronger motivation than “I don’t trust my users not to miss the entire point of my class”. – Davis Herring May 02 '20 at 02:32
  • 1
    In c++ namespace are singleton: https://stackoverflow.com/a/5794619/5632316. Uniqueness is ensured by the "One Definition Rule". C++ is not Java. – Oliv May 02 '20 at 19:57

2 Answers2

0

There is a paper written that proposed this in 2018, (and later 2019). In fact, it appears it was circulated in June of 2019 as part of the Committee's proposal process. However, I'm not really sure what happened to it (other then I think I found another revision).

Some compilers might support it experimentally. If they did, I believe the header you would use is <experimental/reflect> (according to the paper, at least).


Otherwise, you're kind of stuck. It appears reflection was deferred to a later standard, so nothing like this really exists in C++ as it stands. Hopefully it will make it into C++23. But for now we have to wait.

  • They still are talking about reflection, and there is a talk about that at cppcon 2019 [Andrew Sutton “Reflections: Compile-time Introspection of Source Code”](https://www.youtube.com/watch?v=ARxj3dfF_h0), according to that such features are planned for c++23. – t.niese May 02 '20 at 06:43
  • @t.niese Thank you. After posting I did some digging and found that out too. I just updated my answer. –  May 02 '20 at 06:44
-1

Unfortunately, what you are trying to do is not possible. So far, C++ doesn't have reflection features that are powerful enough.

In reality, programmers use singleton classes without needing protection mechanisms like this, because C++ is not designed for maximum compile-time validation. There are a whole lot of other similar things you can't do in C++ — in other words, it is impossible for C++ to accommodate for every possible feature users may expect, especially those that are not generally considered useful. Reflection is proposed because many people find it helpful, but so far the equivalent capabilities have not been included in C++.

L. F.
  • 19,445
  • 8
  • 48
  • 82