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.
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.
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 )
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.
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.
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.
That is a gcc bug fixed in release 4.8.0:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52816
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With