关于在STL中使用范围解析运算符的困惑

时间:2017-10-23 10:05:58

标签: c++ stl

我正在学习C ++的书包括这样的例子:

const int numMembers = tuple_size<tupleType>::value;

而且:

vector <int>::iterator arrIterator = intArray.begin ();

在这两种情况下,我都不清楚如何使用范围解析运算符(::)。在这些例子中,值和迭代器的值究竟是如何确定的?

4 个答案:

答案 0 :(得分:3)

在这两种情况下,限定名称用于命名类模板特化的成员。这可以用于命名静态类成员。此外,typedefusing别名可以出现在类定义或类模板定义中,类型别名也被视为该类的成员。

std::tuple_size<tupleType>::value是一个静态成员(指定元组类型中的元素数)。 std::vector<int>::iterator是一个成员类类型(该类型的对象可用于迭代向量的元素)。

例如:

template <typename T> class A
{
public:
    static const int value = 3;
    typedef int number_type;
    using param_type = T;
    using container_type = std::vector<T>;
};

int main() {
    int a = A<int>::value;          // a is initialized to 3
    A<int>::number_type n = 0;      // n is an int
    A<int>::param_type p = 1;       // p is an int
    A<double>::param_type q = 2.5;  // q is a double
    A<double>::container_type v;    // v is a std::vector<double>
}

(如示例所示,类模板的成员可以依赖于模板参数。)

答案 1 :(得分:1)

tuple_size<tupleType>::value的情况下,value是在tuple_size结构内定义的变量。 ::意味着“查找tuple_size结构中定义的名称值”。

vector <int>::iterator也是如此。 iterator是在vector类中定义的。

您可能会感到困惑,因为示例中的两个外部类型都指定了模板参数。查看vector<int>示例,这使得迭代器(在矢量类中定义内部)知道它将迭代的类型。这就是为什么iterator首先在vector内定义的原因。

tuple_size<tupleType>::value的情况下,这是元组中的参数数量。在这种情况下,value是整数,取决于模板参数,所以它也必须在里面元组类中定义。

答案 2 :(得分:1)

范围解析运算符仅指定查找名称的位置。因此,tuple_size<tupleType>::value表示在类value中查找名称tuple_size<tupleType>。范围解析并不关心名称的含义,它只涉及查找的位置。

使用名称的地方决定了它是否有效使用。

在第一种情况下,它在声明中用作初始值设定项,因此它必须将值命名为有效,如果不是,编译器将会抱怨。而在第二种情况下,它在声明中用于命名类型(iterator)。同样,编译器可以在检查声明后检查它确实是一种类型,并且知道它应该是一个。

当然,这只是一种轻微的简化。在模板的定义中,这些名称依赖于模板参数,其含义可能会发生变化。因此,我们必须明确指定我们期望这些名称的内容,如详细here

答案 3 :(得分:1)

tuple_size<tupleType>vector<int>是模板类。模板参数tupleTypeint是类定义的一部分,这意味着vector<double>例如是一个完全不同的类。

这就是为什么你必须包括它们来解决范围。

最后,它与访问像class::member这样的简单类成员没什么区别。