【发布时间】:2011-08-31 09:33:41
【问题描述】:
假设我有一些 stl 容器类 obj 的对象。我可以这样定义其他相同类型的对象:
decltype(obj) obj2;
但我不能以这种方式为容器声明迭代器:
decltype(obj)::iterator it = obj.begin();
为什么?我做错了吗?
【问题讨论】:
标签: c++ visual-studio-2010 c++11 visual-c++ decltype
假设我有一些 stl 容器类 obj 的对象。我可以这样定义其他相同类型的对象:
decltype(obj) obj2;
但我不能以这种方式为容器声明迭代器:
decltype(obj)::iterator it = obj.begin();
为什么?我做错了吗?
【问题讨论】:
标签: c++ visual-studio-2010 c++11 visual-c++ decltype
根据最终的 C++0x 草案 (FDIS),您的代码格式正确。这是 Visual Studio 编译器尚未实现的后期更改。
与此同时,一种解决方法是使用 typedef:
typedef decltype(obj) obj_type;
obj_type::iterator it = obj.begin();
编辑:相关章节和诗句是 5.1.1/8:
合格 ID: [...] nested-name-specifier 模板optunqualified-id 嵌套名称说明符: [...] decltype-specifier :: decltype-specifier: decltype ( 表达式 )为了完整起见:
【讨论】:
在修复 VC++ 的解析器以反映 FDIS 之前,另一种解决方法是使用 std::identity<> 元函数:
std::identity<decltype(obj)>::type::iterator it = obj.begin();
【讨论】:
std::identity 已被删除,因此这实际上依赖于 VC2010。 (不过写起来很简单。)
这是因为语言的解析方式。
decltype(obj)::iterator it = obj.begin();
你希望它变成
(decltype(obj)::iterator) it;
但实际上却变成了
decltype(obj) (::iterator) it;
我不得不承认,我也很惊讶地发现情况确实如此,因为我确信我以前也这样做过。但是,在这种情况下,您可以只使用auto,甚至可以使用decltype(obj.begin()),但除此之外,您可以这样做
typedef decltype(obj) objtype;
objtype::iterator it;
【讨论】:
auto。但在我看来,typedefing 并不是一个好主意。我这样做是为了避免类型定义。
typedef- 它几乎不是 typedef-free。 typedef 在 C++ 中很难避免。
decltype(obj)::iterator 更具可读性,并且无论如何,DeadMG 提出的可以是 local typedef: void X::foo() { typedef decltype(member) container_t; container_t::begin it...,这不需要你返回并到标题...然后我也不会这样做...