5

Given the following function template from a tutorial.

template<class T>
double GetAverage(T tArray[], int nElements)
{
    T tSum = T(); // tSum = 0

    for (int nIndex = 0; nIndex < nElements; ++nIndex)
    {
        tSum += tArray[nIndex];
    }

    // Whatever type of T is, convert to double
    return double(tSum) / nElements;
}

In the line

T tSum = T(); // tSum = 0

they are saying it will call the default constructor for particular type (based on the type we call this function). My doubt is how this call assigning the value to tSum, as this will call the constructor fine. but since constructor does not return anything how iSum is initialized to 0 for int or 0.0 for double.

Devesh Agrawal
  • 8,982
  • 16
  • 82
  • 131
  • 1
    Related post: [What do the following phrases mean in C++: zero-, default- and value-initialization?](http://stackoverflow.com/q/1613341/183120); reading this will give you more clarity. – legends2k Dec 11 '13 at 08:53

3 Answers3

6

The tutorial you are reading makes some serious terminological distortions/simplifications. The statement saying that

T tSum = T();

calls "default constructor" is incorrect. It is immediately obvious from the fact that in general case type T can easily be a non-class type. Non-class types don't have any constructors, yet the above initialization is valid for them as well.

The proper term in this case is value-initialization. Expression T() produces a temporary object of type T initialized by value-initialization process. Value-initialization works in accordance with its own specific rules, and it does not necessarily involve any constructors at all. It proceeds in completely constructor-less ways for non-class types as well as for some categories of class types.

For example, expression int() produces value 0 of type int - that is what value-initialization means for type int (and for all scalar types). It, of course, does not involve any "default constructors", since type int can't possibly have any constructors.

Again, expression T() in not a constructor call, as that tutorial seems to incorrectly state. Expression T() is actually a functional-style cast with no operand. A functional-style cast with no operand produces, as I said above, a value-initialized temporary object of type T. It does not depend on the constructor "returning" anything.

The temporary value if T() expression is then used as initializer for tSum object. This syntax invokes copy initialization of tSum from T().

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
3

The statement

T tSum = T();

means 'construct temporary of type T using default constructor, then copy/move construct tSum', see C++ n3376 ch8.5, p14. Compiler is allowed (and likely will) optimize it to in-place default construction T tSum;, see C++ n3376 ch12.8, p31, copy elision, but the copy/move constructor must be available, see C++ n3376 ch12.8 p32 (consider deleting copy/move constructors of T and it will fail to compile).

nyrl
  • 769
  • 5
  • 15
1

T() actually creates a temporary object of type T calling the default constructor to initialize it. Then you have the temporary object itself.

So

T tSum = T();

Will initialize tSum with a default initialized temporary instance of T.

If T is a class with a constructor, all this seems unnecesary, but if T is a basic type (such as int) that will initialize tSum to 0. Since when you write the template the nature of T is unknown, the code plays it safe.

rodrigo
  • 94,151
  • 12
  • 143
  • 190