Carpetfizz
Carpetfizz

Reputation: 9169

Vector constructor example with const pointer

I'm reading this tutorial on computer graphics, and ran across the following code example.

template<typename T> 
class Vec3 
{ 
public: 
    // 3 most basic ways of initializing a vector
    Vec3() : x(T(0)), y(T(0)), z(T(0)) {} 
    Vec3(const T &xx) : x(xx), y(xx), z(xx) {} 
    Vec3(T xx, T yy, T zz) : x(xx), y(yy), z(zz) {} 
    T x, y, z; 
}; 

typedef Vec3<float> Vec3f; 

Vec3<float> a; 
Vec3f b; 

I recognize that each constructor is making use of member initializer lists.

  1. The default constructor initializes x, y, and z as 0 of type T

  2. ?

  3. The constructor accepts x, y, and z explicility and initializes the member variables accordingly.

I'm not sure what 2. is trying to illustrate, or how I would use it. What does const T &xx mean exactly? I get that xx is a pointer to some variable of type T, but is the const referring to the pointer itself or the variable it's pointing to? Furthermore, what's the point of initializing x, y, and z with the same variable?

Upvotes: 2

Views: 189

Answers (1)

Thomas
Thomas

Reputation: 182000

const T &xx is a reference (&) to a const T.

By using a reference instead of simply passing T xx, a potentially expensive copy can be avoided, in case T is a complex type. (Might be premature optimization in this case, because your typical Vec3 will only be instantiated with types like float or double, but the compiler will optimize it out anyway.)

By making it a reference to a const T, the caller can be certain that the T they pass in will not be modified by the constructor. Moreover, the caller will be able to pass values that are already const, like literals (e.g. Vec3<double>(1.0)).

The rule with const is: it always refers to the thing that precedes it. So int const *x means that x is a (mutable) pointer to a const int, whereas int *const x means that x is a const pointer to a (mutable) int. int const *const x is also possible.

But what if the const is the first token in the type, so there's nothing that precedes it? Then it "jumps over one", so const T &xx is the same as T const &xx. For consistency, I prefer to write the latter, but many people use the former because it reads more naturally from left to right.

This constructor would be useful if you want a vector set to (1, 1, 1), for instance. Of questionable mathematical meaning, but sometimes useful. For example, by multiplying a vector (x, y, z) by (1, 1, 1) we can easily compute the sum of the components of the former vector.

Upvotes: 3

Related Questions