Reputation: 556
The book I'm learning C++ from includes examples like this:
const int numMembers = tuple_size<tupleType>::value;
And this:
vector <int>::iterator arrIterator = intArray.begin ();
In both cases, it's not entirely clear to me how the scope resolution operator (::) is being used. How exactly are the values of value and iterator determined, respectively, in these examples?
Upvotes: 2
Views: 556
Reputation: 170064
The scope resolution operator only specifies where to look for a name. So tuple_size<tupleType>::value
means to look for the name value
inside the class tuple_size<tupleType>
. Scope resolution doesn't care what the name denotes, it only deals with where it is looked up.
The place where the name is used, is what determines whether or not it is a valid use.
In the first case, it is used in a declaration as an initializer, so it must name a value to be valid, and the compiler will complain if it doesn't. While in the second case, it is used in a declaration to name a type (iterator
). Again, the compiler can check it is indeed a type once it examines the declaration and knows it should be one.
That is a slight simplification, of course. In the definition of templates, where those names are dependent on template parameters, the meaning can change. So we must specify explicitly what we expect those names to be, as detailed here.
Upvotes: 1
Reputation: 5582
In the case of tuple_size<tupleType>::value
, value
is a variable defined inside the tuple_size
struct. The ::
means something like 'look for the name value defined inside the tuple_size struct'.
The same goes for vector <int>::iterator
. The iterator
is defined inside the vector
class.
You might be confused because both outer types in your examples have a template parameter specified. Looking at the vector<int>
example, this makes the iterator (defined inside the vector class) know about the type it will iterate over. That is why iterator
is defined inside of vector
in the first place.
In case of the tuple_size<tupleType>::value
this is the number of arguments in the tuple. value
in this case is in integer that depends on the template parameters so it also has to be defined inside the tuple class.
Upvotes: 1
Reputation: 72311
In both cases, the qualified name is used to name a member of the class template specialization. This can be used to name a static class member. Also, a typedef
or using
alias can appear in a class definition or class template definition, and the type alias name is considered a member of the class.
std::tuple_size<tupleType>::value
is a static member (which specifies the number of elements in the tuple type). std::vector<int>::iterator
is a member class type (and objects of that type can be used to iterate over the vector's elements).
For example:
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>
}
(As the example shows, a member of a class template can depend on template arguments.)
Upvotes: 3
Reputation: 12047
tuple_size<tupleType>
and vector<int>
are template classes. The template parameters tupleType
and int
are a part of the class definition, that means a vector<double>
for example is a completely different class.
That's why you have to include them to resolve the scope.
In the end it's not different from accessing a simple class member like class::member
.
Upvotes: 1