我正在学习C ++的书包括这样的例子:
const int numMembers = tuple_size<tupleType>::value;
而且:
vector <int>::iterator arrIterator = intArray.begin ();
在这两种情况下,我都不清楚如何使用范围解析运算符(::)。在这些例子中,值和迭代器的值究竟是如何确定的?
答案 0 :(得分:3)
在这两种情况下,限定名称用于命名类模板特化的成员。这可以用于命名静态类成员。此外,typedef
或using
别名可以出现在类定义或类模板定义中,类型别名也被视为该类的成员。
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>
是模板类。模板参数tupleType
和int
是类定义的一部分,这意味着vector<double>
例如是一个完全不同的类。
这就是为什么你必须包括它们来解决范围。
最后,它与访问像class::member
这样的简单类成员没什么区别。