以类作为typename的模板变量



我正在学习C++14,因为我遇到了这个模板变量特性,我对此感兴趣,并尝试了多个例子来理解模板变量。比如

template <typename T>
T var;
var<int>;
var<float>;

上面的代码起了作用,它看起来也很直观。但是,当我尝试使用类名来代替int或float时,结果调用了类FOO的临时对象创建,并调用了相应的C'tor&临时对象的dtor。

var<FOO>;  //FOO is a class

我已经编写了一个示例测试程序及其输出,以供您理解。我的问题是,

  1. var为什么创建临时对象
  2. 基元数据类型和用户定义的数据类型的模板变量有何不同

如果它不相关或重复,请向我指出来源,以便我清楚地理解。

参考以下代码,

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>;
}

输出:

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

这个简单的程序不会创建临时对象:

int main() {
var<SomeClass>;
}

这里创建了一个临时对象:

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

但那是因为我们用CCD_ 1做的。然后,我们将其分配给var<SomeClass>非临时对象(在您的许多示例中是全局的(。

这里运行的代码是

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

按照这个顺序。

#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 mainn";
{
var<noisy> = noisy{};
std::cout << "Body of mainn";
}
std::cout << "End of mainn";
}

活生生的例子。

输出:

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