Reputation: 11098
Say I have an object of some of stl container classes obj
. I can define other object of same type this way:
decltype(obj) obj2;
But I can't declare iterator for the container this way:
decltype(obj)::iterator it = obj.begin();
Why? Am I doing something wrong?
Upvotes: 11
Views: 2826
Reputation: 14421
Your code is well-formed according to the final C++0x draft (FDIS). This was a late change that's not yet been implemented by the Visual Studio compiler.
In the meantime, a workaround is to use a typedef:
typedef decltype(obj) obj_type;
obj_type::iterator it = obj.begin();
EDIT: The relevant chapter and verse is 5.1.1/8:
qualified-id: [...] nested-name-specifier templateopt unqualified-id nested-name-specifier: [...] decltype-specifier :: decltype-specifier: decltype ( expression )
And for completeness's sake:
Upvotes: 16
Reputation: 62975
Yet another workaround until VC++'s parser is fixed to reflect the FDIS is to use the std::identity<>
metafunction:
std::identity<decltype(obj)>::type::iterator it = obj.begin();
Upvotes: 2
Reputation: 146910
It's because of the way that the language is parsed.
decltype(obj)::iterator it = obj.begin();
You want it to become
(decltype(obj)::iterator) it;
But in actual fact, it becomes
decltype(obj) (::iterator) it;
I have to admit, I was also surprised to see that this was the case, as I'm certain that I've done this before. However, in this case, you could just use auto
, or even decltype(obj.begin())
, but in addition, you can do
typedef decltype(obj) objtype;
objtype::iterator it;
Upvotes: 9