为什么在C ++中container.value_type是非法的

时间:2013-11-11 14:03:34

标签: c++ language-lawyer

以下代码是非法的:

#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'));

让代码工作。

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

3 个答案:

答案 0 :(得分:8)

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

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

现在怎样?你不能从上下文告诉X.X应该是什么。

这就是.::在语言中的原因 - X.X()是指成员函数调用,而X::X是指类型。

答案 1 :(得分:1)

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

decltype(v)解析为对象v的基础类类型,因此在这种情况下它等同于编写std::vector<std::pair<int, char> >。然后使用范围运算符::来访问类项。

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

答案 2 :(得分:0)

因为运营商.->用于成员访问(通常)。你无法访问任何抽象的东西,只能访问有形物体。而类型是一个抽象的东西。因此,您必须使用::

访问它