Why are access declarations deprecated? What does this mean for SRO and using declarations?

StackOverflow https://stackoverflow.com/questions/22441288

  •  15-06-2023
  •  | 
  •  

Domanda

I've been looking high and low for an answer to what I thought was a fairly simple question: Why are access declarations deprecated?

class A
{
public:
    int testInt;
}

class B: public A
{
private:
   A::testInt;
}

I understand that it can be fixed by simply plopping "using" in front of A::testInt, but without some sort of understanding as to why I must do so, that feels like a cheap fix.

Worse yet, it muddies my understanding of using declarations/directives, and the scope resolution operator. If I must use a using declaration here, why am I able to use the SRO and only the SRO elsewhere? A trivial example is std::cout. Why not use using std::cout? I used to think that using and the SRO were more or less interchangeable (give or take some handy functionality provided with the "using" keyword, of which I am aware, at least in the case of namespaces).

I've seen the following in the standard:

The access of a member of a base class can be changed in the derived class by mentioning >its qualified-id in the derived class declaration. Such mention is called an access >declaration. The effect of an access declaration qualified-id; is defined to be equivalent >to the declaration using qualified-id; [Footnote: Access declarations are deprecated; member >using-declarations (7.3.3) provide a better means of doing the same things. In earlier >versions of the C++ language, access declarations were more limited; they were generalized >and made equivalent to using-declarations - end footnote]

However, that really does nothing other than confirm what I already know. If you really boiled it down, I am sure my problem stems from the fact that I think using and the SRO are interchangeable, but I haven't seen anything that would suggest otherwise.

Thanks in advance!

È stato utile?

Soluzione

If I must use a using declaration here, why am I able to use the SRO and only the SRO elsewhere?

Huh? You are not able to. Not to re-declare a name in a different scope (which is what an access declaration does).

A trivial example is std::cout. Why not use using std::cout?

Because they're not the same thing, not even close.

One refers to a name, the other re-declares a name.

I am sure my problem stems from the fact that I think using and the SRO are interchangeable

I agree that's your problem, because you are entirely wrong. Following a using declaration it is not necessary to qualify the name, but that doesn't make them interchangeable.

std::cout is an expression, it refers to the variable so you can write to it, pass it as a function argument, take its address etc.

using std::cout; is a declaration. It makes the name cout available in the current scope, as an alias for the name std::cout.

std::cout << "This is an expression involving std::cout\n";
using std::cout;  // re-declaration of `cout` in current scope

If you're suggesting that for consistency you should do this to write to cout:

using std::cout << "This is madness.\n";

then, erm, that's madness.

In a class, when you want to re-declare a member with a different access you are re-declaring it, so you want a declaration. You aren't trying to refer to the object to write to involve it in some expression, which (if it was allowed at class scope) would look like this:

class B: public A
{
private:
   A::testInt + 1;
};

For consistency with the rest of the language, re-declaring a name from a base class is done with a using-declaration, because that's a declaration, it's not done with something that looks like an expression.

class B: public A
{
private:
   A::testInt; // looks like an expression involving A::testInt, but isn't
   using A::testInt;  // re-declaration of `testInt` in current scope
};

Compare this to the std::cout example above and you'll see that requiring using is entirely consistent, and removing access declarations from C++ makes the language more consistent.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top