Saravanan
Saravanan

Reputation: 1440

Template variables with class as typename

I am learning C++14, in that come across this template variable feature and that interested me to dig more on this and i tried with multiple examples to understand the template variables. Say,

template <typename T>
T var;

var<int>;
var<float>;

Above code worked and it looked straight forward to understand too. But, when I tried to use class name in place of int or float as shown above, result in calling the temporary object creation for the class FOO and calling corresponding C'tor & dtor for the temp object.

var<FOO>;  //FOO is a class

I have written a sample test program and its output for your understanding. My question is that,

  1. Why var creates temp object?
  2. How template variable differ for primitive datatypes and user defined datatypes?

If it is irrelevant or duplicate, please point me to the source for clear understanding.

Refer code below,

class B
{
  public:
  B()
  {
      std::cout<<"\nB ctor"<<std::endl;
  }
  B(const B& obj)
  {
      std::cout<<"B copy ctor"<<std::endl;
  }
  int operator()()
  {
      std::cout<<"operator() called"<<std::endl;
  }
   void f()  {
   //::A().print();   
  }
  ~B()
  {
      std::cout<<"\n~ for B()"<<std::endl;
  }
  
};

//Declaring template variable
template<typename T>
 T g ;

int main() {
    g<int> = 30;
    g<float> = 30.02f;
    g<B> = B{};
    std::cout<<"g value:"<<g<int><<std::endl;
    std::cout<<"g value:"<<g<float>;
}

Output:

B ctor                                                                                                                                         
g value:30                                                                                                                                     
g value:30.02                                                                                                                                  
~ for B()   

Upvotes: 0

Views: 302

Answers (1)

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275340

No temporary object is created by this simple program:

int main() {
  var<SomeClass>;
}

A temporary object is created here:

int main() {
  var<SomeClass> = SomeClass{};
}

but that is because we did it with SomeClass{}. We then assigned that to the var<SomeClass> non-temporary object (global in many of your examples).

The code that runs here is

 SomeClass::SomeClass()
 SomeClass::SomeClass()
 SomeClass::operator=(SomeClass&&)
 SomeClass::~SomeClass()
 SomeClass::~SomeClass()

in that order.

#include <iostream>

struct noisy {
  noisy() { std::cout << __func__ << "()\n"; }
  ~noisy() { std::cout << __func__ << "()\n"; }
  noisy(noisy&&) { std::cout << __func__ << "(&&)\n"; }
  noisy(noisy const&) { std::cout << __func__ << "(c&)\n"; }
  void operator=(noisy&&) { std::cout << __func__ << "(&&)\n"; }
  void operator=(noisy const&) { std::cout << __func__ << "(c&)\n"; }
};

template<class T>
T var;

int main() {
    std::cout << "Start of main\n";
    {
        var<noisy> = noisy{};
        std::cout << "Body of main\n";
    }
    std::cout << "End of main\n";
}

live example.

Output:

noisy()
Start of main
noisy()
operator=(&&)
~noisy()
Body of main
End of main
~noisy()

Upvotes: 2

Related Questions