完美转发函数

#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();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值