关于C++中函数类型的隐式转换

在编写如下代码时发生错误:

template<typename T>
bool compare(T first, T second,function<bool(T,T)>cp)
{
    return cp(first,second);
}

string a("Wu"),b("Han");
cout<<compare(a,b,[](string a,string b){
    return a.size() < b.size();
});
> 编译的报错点在compare上,经过反复测试,发现问题出现在由lambda表达式实参到function类型的转换上。这种转换实际上是一种隐式转换。也就是说,在执行function的这种隐式转换前,函数并不能通过这种不同类型(一个是function,一个是lambda)的实参推断出形参的模板参数。

> 也就是说,只要我们能够在隐式转换前得到函数的形参模板参数,这种调用便可以正常发生。于是我做出如下几种修改:
//第一种方式
template<typename T>
bool compare(T first,T second,function<bool(T,T)>cp){
    return cp(first,second);
}

string a("Wu"),b("Han");

cout<<compare<string>(a,b,[](string a,string b){
    return a.size() < b.size();
});//调用函数时指定函数模板类型


----------


//第二种方式
template<typename T>
bool compare(T first,T second,function<bool(T,T)>cp){
    return cp(first,second);
}

string a("Wu"),b("Han");

function<bool<string,string>> c = [](string a,string b){
    return a.size() < b.size();
}

cout<<compare(a,b,c);//避免这种由lambda到function的隐式转换


----------


//第三种方式
template<typename T>
struct type_deduce{
    using type T;
};

template<typename T>
bool compare(T first,T second,typename type_deduce<function<bool(T,T)>>::type cp){
    return cp(first,second);
}

string a("Wu"),b("Han");

cout<<compare(a,b,[](string a,string b){
    return a.size() < b.size();
});//一种特别的方式解决问题,依然用了向模板的隐式转换
> 第三种情况有点特殊,我们没有显式的指定形参模板类型,我们靠着隐式转换实现了之前未能实现的操作。因为我们的function的模板依赖于前两个形参,也就是说,一旦我们知道了前面两个类型,我们便有了能够推断出的能力。但是我们必须让这个推断过程先于匹配过程,因此,我们加入了这个type_deduce。编译器解析完前两个参数,要确定第三个参数的在模板函数声明时候的类型(即type),被迫去算第三个参数的type_deduce中的type是什么,这样就把function的模板参数给解析出来了。


    到此,我的问题算是解决了,同样,我测试了隐式转换的几种情况,分别与以上的代码对应。
//测试一:隐式转换在模板间发生
template<typename T>
class A{};

template<typename T>
class B
{
    public:
        operator A<T>(){return A<T>();}
};

template<typename T>
void fun(A<T> a){
    std::cout<<"fun works"<<std::endl;
}

int main(){
    fun(B<int>());//wrong B cannot be converted into A.
    A<int> a = B<int>();
    fun(a);//ok
    return 0;
}


----------

//测试二:当形参不为模板时,这种隐式转换发生

class A{};

template<typename T>
class B
{
    public:
        operator A(){return A();}
};

template<typename T>
void fun(A a){
    std::cout<<"fun works"<<std::endl;
}

int main(){
    fun(B<int>());//ok
    return 0;
}

----------

//测试三:实现向模板形参的隐式转换,方法是借助已经解析的模板参数
template<typename T>
strcut type_deduce{
    using type T;   
};

template<typename T>
class A{};

template<typename T>
class B
{
    public:
        operator A<T>(){return A<T>();}
};

template<typename T>
void fun(T,typename type_deduce<B<int>()>::type){
    std::cout<<"fun works"<<std::endl;
}

int main(){
    fun(1,B<int>());//ok
    return 0;
}



到现在,所有的测试及问题已经全部解决!!!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值