#include <iostream>
class Person{
public:
// 完美转发用于构造函数
template<typename STR>
Person(STR&& n):name(std::forward<STR>(n)) {
std::cout<<"tmpl-conster"<<std::endl;
}
Person(const Person& p):name(p.name){
std::cout<<"copy constructor"<<std::endl;
}
Person(Person&& p): name(std::move(p.name)){
std::cout<<"move constructor"<<std::endl;
}
private:
std::string name;
};
void Test(){
std::string str="hello";
Person p(str); // tmpl-conster
Person p1("tmp");// tmp-conster;
// error, 模板构造函数copy constructor 函数(有const限定符)比更适合
// 但模板构造函数不是拷贝构造函数实现,所以报错,当然在添加个非const拷贝
// 构造函数可以解决报错,最好处理时禁用模板构造函数,后调用带有const的万能引用拷贝构造函数
/*
Person(Person& p):name(p.name){}
*/
// Person p2(p1);
Person p2(std::move(p1)); // move constructor
}
template<typename T>
using EnableIfString = typename std::enable_if<std::is_convertible<T, std::string>::value>::type;
class Person1{
public:
//若STR类型到std::string不是可转换,则禁用模板函数
// 写法太复杂,可以使用模板别名
//template<typename STR, typename=typename std::enable_if<std::is_convertible<STR, std::string>::value>::type>
template<typename STR, typename=EnableIfString<STR>> // EnableIfString使用更简易
Person1(STR&& n):name(std::forward<STR>(n)) {
std::cout<<"tmpl-conster"<<std::endl;
}
Person1(const Person1& p):name(p.name){
std::cout<<"copy constructor"<<std::endl;
}
Person1(Person1&& p): name(std::move(p.name)){
std::cout<<"move constructor"<<std::endl;
}
private:
std::string name;
};
void Test1(){
Person1 p("tmp");
Person1 p1(p);// copy constructor, p不是string类型,模板构造函数被禁用,只能调用拷贝构造函数
}
int main(){
Test();
Test1();
}
完美转发函数
最新推荐文章于 2024-09-08 00:02:44 发布
这篇博客探讨了C++中的完美转发在构造函数中的应用,以及如何通过模板和std::enable_if禁用特定类型的构造。文章通过示例展示了如何使用模板构造函数和拷贝/移动构造函数,并解释了为何模板构造函数不能作为拷贝构造函数的替代。同时,还介绍了如何利用模板别名简化代码。
588

被折叠的 条评论
为什么被折叠?



