#include <iostream>
#include <utility>
#include <memory>
#include <stdio.h>
template<typename T, typename... Ts>
std::unique_ptr<T> make_unique(Ts&&... params)
{
return std::unique_ptr<T>(new T(std::forward<Ts>(params)...));
}
class Executor{
public:
virtual ~Executor(){}
virtual bool Run()=0;
};
template <class Closure>
class ClosureExector:public Executor{
public:
explicit ClosureExector(Closure &&closure):
closure_(std::forward<Closure>(closure)){}
~ClosureExector(){
}
private:
bool Run() override{
closure_();
return true;
}
typename std::decay<Closure>::type closure_;
};
template<class Closure>
std::unique_ptr<Executor> ToTask(Closure &&closure)
{
return make_unique<ClosureExector<Closure>>(std::forward<Closure>(closure));
}
class Callback{
public:
Callback(){}
void Call(){
if(exec_){
exec_->Run();
}else{
printf("wtf\n");
}
}
//but this operation is problematic
// PostTask(make_unique<ClosureExector<Closure>>(std::forward<Closure>(closure)))
//使用这个语句导致编译很慢
template <class Closure>
void PostTask(Closure &&closure){
//PostTask(make_unique<ClosureExector<Closure>>(std::forward<Closure>(closure)));
PostTask(ToTask(std::forward<Closure>(closure)));
}
void PostTask(std::unique_ptr<Executor> exec){
exec_=std::move(exec);
}
// if add this ,PostTask(make_unique.. seems work normal again.
/*template <class Closure>
void PostTask(std::unique_ptr<ClosureExector<Closure>> exec){
printf("match2\n");
std::unique_ptr<Executor> cast=std::move(exec);
PostTask(std::move(cast));
}*/
private:
std::unique_ptr<Executor> exec_;
};
void Test1(Callback *call){
call->Call();
}
void Test2(Callback *call){
int a=1,b=2;
call->PostTask([a,b](){
printf("%d,%d\n",a,b);
});
}
int main(){
Callback call;
Test2(&call);
Test1(&call);
call.Call();
return 0;
}
我发现这个语句导致很长的编译时间,甚至不能成功编译。
template <class Closure>
void PostTask(Closure &&closure){
PostTask(make_unique<ClosureExector<Closure>>(std::forward<Closure>(closure)));
}
但是增加了如下的强制类型转换又可以正常工作了。
template <class Closure>
void PostTask(Closure &&closure){
PostTask(make_unique<ClosureExector<Closure>>(std::forward<Closure>(closure)));
}
template <class Closure>
void PostTask(std::unique_ptr<ClosureExector<Closure>> exec){
std::unique_ptr<Executor> cast=std::move(exec);
PostTask(std::move(cast));
}
刚开始我并不知道是什么原因,导致了非常长的编译时间。不断写函数测试,模拟这个情况,灵光乍现,我觉是这个原因,模板函数在匹配的过程中,引起了死循环。
template <class Closure>
void PostTask(Closure &&closure){
PostTask(make_unique<ClosureExector<Closure>>(std::forward<Closure>(closure)));
//这里并不会调用void PostTask(std::unique_ptr<Executor> exec),
而是会不断调用自己,引起一个死循环,不断调用自己,累死编译器。
}
And a similar case:
#include <iostream>
#include <utility>
#include <memory>
#include <stdio.h>
template<typename T, typename... Ts>
std::unique_ptr<T> make_unique(Ts&&... params)
{
return std::unique_ptr<T>(new T(std::forward<Ts>(params)...));
}
class Interface{
public:
virtual void Print()=0;
virtual ~Interface(){}
};
template <typename T>
class Parent: public Interface{
public:
Parent(T t):t_(t){}
virtual void Print(){
std::cout<<t_<<std::endl;
}
virtual ~Parent(){
}
private:
T t_;
};
template <typename T>
class Child:public Parent<T>{
public:
Child(T t):Parent<T>(t){}
virtual void Print(){
Parent<T>::Print();
printf("hello child\n");
}
~Child(){}
};
class Call{
public:
Call(){}
~Call(){
if(exec_){
delete exec_;
}
}
void CallFun(){
if(exec_){
exec_->Print();
}else{
printf("wtf\n");
}
}
template<class T>
void Post(T t){
Child<T>* e=(new Child<T>(t));
Post((Interface*)e);
}
void Post(Interface* exec){
printf("post\n");
exec_=exec;
}
private:
Interface *exec_{nullptr};
};
int main(){
Call call;
call.Post(12);
call.CallFun();
return 0;
}
网友评论