Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is decltype not allowed on private member variables?

Suppose I have a class like this:

class Foo
{
  std::vector<int> bar;

public:
  std::vector<int>& get_bar() { return bar; }
};

and later on, I want another variable somewhere else that has the same type as bar. It would make sense to me if I could just do this:

decltype(Foo::bar) clone_of_bar;

But that doesn't work. The compiler tells me 'std::vector< int > Foo::bar' is private.

So I end up having to use something like this:

std::remove_reference<decltype(std::declval<Foo>().get_bar())>::type clone_of_bar;

Which works, but looks like a complete mess. Maybe there's an easier way to do it; I'm not really sure. But what I really want to know is why I can't just use decltype(Foo::bar). Why should anyone care that bar is private? It's not like I'm actually accessing the variable.

decltype is a new feature of the language. I just don't understand why it was designed to not work on private variables.

like image 886
karadoc Avatar asked Jun 07 '12 00:06

karadoc


People also ask

Where is decltype used?

The decltype type specifier, together with the auto keyword, is useful primarily to developers who write template libraries. Use auto and decltype to declare a template function whose return type depends on the types of its template arguments.

What does decltype stand for?

Decltype keyword in C++ Decltype stands for declared type of an entity or the type of an expression. It lets you extract the type from the variable so decltype is sort of an operator that evaluates the type of passed expression. SYNTAX : decltype( expression )

What does decltype return?

decltype returnsIf what we pass to decltype is the name of a variable (e.g. decltype(x) above) or function or denotes a member of an object ( decltype x.i ), then the result is the type of whatever this refers to.


3 Answers

In language lawyer terms, bar is a name, to use it in the decltype expression the compiler has to do normal name lookup, which respects access control.
Why should decltype have been designed differently to the rest of the language? You haven't presented any convincing argument for why it shouldn't be consistent with e.g. sizeof.

As a class author, I don't want you to be able to query private implementation details like that. If I wanted the type to be usable outside the class I'd define a public typedef telling you what type it is.

and later on, I want another variable somewhere else that has the same type as bar

You want "another variable" that's the same type as a private implementation detail? So if the author of class Foo refactors their code and replaces the type with some other implementation detail, suddenly your code changes meaning and unrelated code might suddenly stop compiling or silently have different behaviour, because that code foolishly relied on private details that were none of its business. That would introduce coupling between private implementation details and unrelated code that the author of Foo might not even know exists! That's a terrible idea.

like image 139
Jonathan Wakely Avatar answered Oct 21 '22 17:10

Jonathan Wakely


decltype(Foo::bar) does work inside Foo.

Outside Foo, you're not even supposed to know that Foo has a member named bar (that's what private means), so of course it shouldn't work.

like image 13
HighCommander4 Avatar answered Oct 21 '22 15:10

HighCommander4


That is a gcc bug fixed in release 4.8.0:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52816

like image 1
Giuppo Avatar answered Oct 21 '22 17:10

Giuppo