简体   繁体   中英

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()

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM