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?
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 templateoptunqualified-id nested-name-specifier: [...] decltype-specifier :: decltype-specifier: decltype ( expression )
And for completeness's sake:
The original core issue
Proposal for wording
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;
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();
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