0

I have this code below which I was trying out from a course I was undertaking, that pretty much does what is expected to do

#include <iostream>

template <typename T, class U = int>
class A {
public:
    T x;
    U y;
    A(T x, U y) { std::cout << x << " " << y << std::endl; }
};

int main() {
    A<char> a('A', 'A');
    A<char, int>('A', 65);
    A<char, char>('A', 'A');
    return 0;
}

But I don't understand how the parts below work. I understand how the default parameters part of the template work, but don't understand how the code creates an object once the template class is instantiated.

A<char, int>('A', 65);
A<char, char>('A', 'A');

Why isn't an explicit object created like for the first case with A<char> a('A', 'A');? I saw no compilation errors compiling with g++ -Wall -Wextra --std=c++11. Also if a specific clause from cppreference that explains this behavior would be appreciated, as I've missed identifying where does such a behavior is explained.

Inian
  • 80,270
  • 14
  • 142
  • 161
  • 3
    I can't tell you why they don't give the objects name, but since they didn't what it does is create a temporary object that is destroyed at the `;` after the declaration. – NathanOliver Sep 25 '19 at 18:17
  • @NathanOliver: Is this officially documented or compiler specific? such temporary objects are known to be used elsewhere? – Inian Sep 25 '19 at 18:28
  • 2
    It is required to be supported by all compilers due to different sections of the C++ standard. This is something that happens a lot. Lets say you have a function that takes an `A` that you don't care about. Instead of creating the `A` object and giving it a name, you can just do `function(A('A', 'A'));` – NathanOliver Sep 25 '19 at 18:34

1 Answers1

1
// Explicit instantiation of A<char, int>.
// The result of the constructor call A(char x, int y) is not used, i.e. 
// is not bound to a name as in A<char> a('A', 'A'); however, because the
// constructor has a side effect of calling std::cout, we can still tell that
// it ran.
A<char, int>('A', 65);

// Explicit instantiation of A<char, char> that is not bound to a name.
A<char, char>('A', 'A');

Observe that you could give names b, c and d or any other valid identifier to the other A's and still see the same result; or, since the one named a is not used after its definition, you could also remove that name and just have it be a call to the constructor that doesn't get bound to a name like the others. Same results for this particular program regardless, although if there was something else you wanted to do with a, b, c or d later after construction, they would need to be referenced by a name.

Aaron Altman
  • 1,705
  • 1
  • 14
  • 22