readyready15728
readyready15728

Reputation: 556

Confusion about use of scope resolution operator in STL

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

Answers (4)

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

gonutz
gonutz

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

aschepler
aschepler

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

alain
alain

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

Related Questions