2
template <class T>
...
explicit Vec(size_type n, const T& t = T() ) { create(n, t); }

I come across this declaration in 'accelerated c++' and the 'Vec' class is simulating the behavior of 'vector' class in STL. But I don't know what will happen if I don't provide the second argument when I call this constructor. I am confused about this because I learned from the book that there is no return value of any constructor? So how can T() be used to initialize t? I a novice of C++. Could anyone elaborate relevant story to me?

Chris Jing
  • 39
  • 5
  • You don't specify a return value ***in the declaration*** of a constructor. But this doesn't mean that "there is no return value". The return is just handled automatically by the compiler. If constructors didn't return anything, how would `MyClass var(a, b, c);` assign the new instance to the `var` variable? – Disillusioned Mar 24 '18 at 14:40
  • Welcome to the site! Check out the [tour](https://stackoverflow.com/tour) and the [how-to-ask page](https://stackoverflow.com/help/how-to-ask) for more about asking questions that will attract quality answers. You can [edit your question](https://stackoverflow.com/posts/49465901/edit) to include more information. – cxw Mar 24 '18 at 14:43
  • @荆泽宇 Correct. The default value of the second parameter would be a newly created instance of the type `T` using the default (parameterless) constructor. Obviously that means that the template only works with classes that have not removed the default constructor in some way. – Disillusioned Mar 24 '18 at 14:46
  • @CraigYoung There is no return value involved here. There is an assign to a reference, same as for example: `int a; const int& b = a;` – super Mar 24 '18 at 15:00
  • @super You're missing the point. An object is created and assigned. The syntactic sugar of the language hides this from you. But if it didn't happen, the whole language would fall apart. – Disillusioned Mar 25 '18 at 00:22
  • @CraigYoung I don't think so. Just because you can assign to a temporary value/object, that doesn't somehow mean that there is a return value in a constructor. – super Mar 25 '18 at 00:30
  • @super You're welcome to think whatever you choose. But flawed thinking is likely to lead to confusion; just as OP was confused. Object construction returns an object no matter what language you use; understand this and other language become easier to learn. _I challenge you to come up with a general purpose assembler implementation for object construction that does not return the newly constructed object in one of 2 places: a predetermined location that the calling code will use to retrieve the object; or location specified by the calling code when it called the constructor._ – Disillusioned Mar 25 '18 at 03:06

4 Answers4

2

This specific statement (isolating it from the surrounding code)

const T& t = T()

creates a temporary object of type T and then the constant reference function argument t then refers to the memory location of that newly created temporary object. The constructor doesn't have a return value in the typical sense, but this procedure effectively creates and returns a new object of that type.

In brief, this is just creating a default object to copy into the vector. Notably, if your particular type T did not have a default constructor like this, then this call would fail unless you explicitly passed an object to the second argument.

Daniel
  • 1,291
  • 6
  • 15
  • So is `const T& t = T()` here the same as `T t` in the definition statement? – Chris Jing Mar 24 '18 at 14:59
  • @荆泽宇 I see where you are coming from and it is a good idea but it is not really the same. If you directly replace `const T& t = T()` with `T t`, then you would need to pass a second argument to the constructor. If you replaced it with `T t = T()`, then that would be closer. However, that may cause you to copy the temporary object into your variable `t`. If you passed an object of type `T`, it would have to copy that object into `t`. The constant reference eliminates unnecessary copying, so even though its usage for the user would be similar the underlying operations are not – Daniel Mar 24 '18 at 15:09
1

T() is an expression that creates a new instance of type T.† Therefore, T() has type T. const T& t can hold a reference to a T, and specifically can hold a reference to the thing created by T(). If you don't provide the second argument to the Vec constructor, the t will be whatever T is by default.

cxw
  • 16,685
  • 2
  • 45
  • 81
0

If the second argument is not supplied explicitly then the compiler creates a temporary object using the default constructor T() and passes a constant reference to this temporary object as the second argument.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

the second parameter is an default/optional parameter, that means it will be automatically assumed as T() or a new instance of T if you omit that...

examples about how optional parameters work

int myMathPowerFunction(int base, int exp = 2){

}

now, since the parameter exp is defined as optional, you could omit it when calling the function, so this myMathPowerFunction(2, 3) is as valid as myMathPowerFunction(2), considering that the compiler will put the 2nd parameter for you myMathPowerFunction(2, 2)

not in your template the optional parameter is an instance of the type T...

ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97