3

以下代码是非法的:

#include <vector>
#include <utility>

int main() {
    std::vector<std::pair<int, char> > v;
    v.push_back(v.value_type(0, 'a')); // *
}

我必须将 * 更改为

v.push_back(decltype(v)::value_type(0, 'a'));

让代码工作。

为什么标有 * 的行不允许?这个理由背后的原因是什么?

4

3 回答 3

8

.总而言之,这是因为 C 对类型和变量有单独的命名空间,这意味着如果可以使用这种方式访问​​成员和类型,那么您可以构建由于 C++ 中的歧义而无法访问成员的场景。并且更改命名空间规则会破坏与合法 C 代码的兼容性。

struct s1 { typedef int X; };
struct s2 { void X(); };
typedef struct s1 X;
struct s2 X;
int main() {
    X.X();
}

怎么办?您无法从上下文中判断 XX 应该是什么。

这就是为什么.and ::are 在语言中X.X()- 指的是成员函数调用,并且X::X指的是一种类型。

于 2013-11-11T14:15:51.023 回答
2

v是一个对象,并v.value_type试图访问value_type,就好像它是对象的成员一样。这是不正确的,因为value_type属于类,而不是实例。(附带说明,typedef 始终属于该类,因为它们在编译时是固定的......即不同的实例不能有不同的副本。)

decltype(v)解析为 object 的底层类类型v,所以在这种情况下它相当于 write std::vector<std::pair<int, char> >。然后使用范围运算符::让您访问类项目。

其他一些语言不会费心区分成员和类访问运算符(.::)。C++ 主要出于与 C 相关的历史原因。

于 2013-11-11T14:23:33.267 回答
0

因为运营商.and->用于成员访问(通常)。你不能用它访问任何抽象的东西,只能访问有形的对象。类型是一个抽象的东西。所以你必须访问它::

于 2013-11-11T14:07:16.703 回答