C++ 将lambda直接传递给函数
我正在编写一个C++ 将lambda直接传递给函数,c++,c++11,C++,C++11,我正在编写一个选项类,它表示一个可能存在或不存在的值。if_opt函数旨在获取一个选项和一个函数,该函数将根据选项中的值调用,但仅当该值存在时才调用 template <class T> class Option { private: std::shared_ptr<T> m_value; public: explicit operator bool()const noexcept { return (bool)m_value;
选项
类,它表示一个可能存在或不存在的值。if_opt
函数旨在获取一个选项
和一个函数,该函数将根据选项
中的值调用,但仅当该值存在时才调用
template <class T>
class Option {
private:
std::shared_ptr<T> m_value;
public:
explicit operator bool()const noexcept
{
return (bool)m_value;
}
Option() = default;
explicit Option(T value)
{
m_value = std::make_shared<T>(value);
}
template <class U>
friend void if_opt(Option<U>&, std::function<void(U&)>);
};
template <class T>
void if_opt(Option<T>& opt, std::function<void(T&)> f)
{
if (opt) f(*opt.m_value);
};
模板
类选项{
私人:
std::共享_ptr m_值;
公众:
显式运算符bool()const noexcept
{
返回(bool)m_值;
}
选项()=默认值;
显式选项(T值)
{
m_值=标准::使_共享(值);
}
模板
如果_opt(选项&标准::函数),则友元无效;
};
模板
如果选择无效(选项&opt,标准::函数f)
{
if(opt)f(*opt.m_值);
};
我注意到,如果我这样使用它,它会起作用:
Option<int> none;
Option<int> some(10);
function<void(int&)> f1 = [](int& none)
{
cout << "This should never be reached" << endl;
};
function<void(int&)> f2 = [](int& some)
{
cout << "The value of some is: " << some << endl;
};
if_opt(none, f1);
if_opt(some, f2);
选项无;
方案一(10);
函数f1=[](int&none)
{
coutstd::function
是一种类型擦除工具。它擦除(几乎)它存储的expet值的所有内容,这些内容可以通过Sig
调用
模板参数推断采用传入的类型并推断应使用的类型,然后生成并(通常)调用模板函数
在类型擦除模板上进行推断是一种代码气味,而且几乎总是一个坏主意
这就是你的基本设计错误
有许多方法可以修复代码
首先,if_opt
不应该是模板
friend void if_opt(Option<T>& opt, std::function<void(T&)> f){
if (opt) f(*opt.m_value);
}
这是一个更好的设计
你可以去投资SFINAE重载解析代码,但我不会费心
template<class F,
std::conditional_t<true, bool,std::result_of_t<F&(T&)>> = true
>
friend void if_opt(Option<T>& opt, F&& f){
if (opt) f(*opt.m_value);
}
模板
如果选择,则朋友无效(选项和选项,F和F){
if(opt)f(*opt.m_值);
}
上面的代码是模糊的,与上面的代码相比具有最小的边际优势。std::function
是一种类型擦除工具。它擦除(几乎)它存储的excpet值的所有可以用Sig
调用的内容
模板参数推断采用传入的类型并推断应使用的类型,然后生成并(通常)调用模板函数
在类型擦除模板上进行推断是一种代码气味,而且几乎总是一个坏主意
这就是你的基本设计错误
有许多方法可以修复代码
首先,if_opt
不应该是模板
friend void if_opt(Option<T>& opt, std::function<void(T&)> f){
if (opt) f(*opt.m_value);
}
这是一个更好的设计
你可以去投资SFINAE重载解析代码,但我不会费心
template<class F,
std::conditional_t<true, bool,std::result_of_t<F&(T&)>> = true
>
friend void if_opt(Option<T>& opt, F&& f){
if (opt) f(*opt.m_value);
}
模板
如果选择,则朋友无效(选项和选项,F和F){
if(opt)f(*opt.m_值);
}
上面的内容是模糊的,与上面的内容相比具有最小的边际优势。如果_opt(Option&opt,F F){…}
FWIW,有一些std::optional
的实现可以与C++11一起使用。Ashared_ptr
因为这太过分了,对于if_opt
的std::function
也太过分了,因为它从来没有被存储过。@IgorTandetnik老实说,这就是我想要的。我觉得不只是这么做太傻了。我接受这个答案@chris谢谢,我不知道std::optional
你知道这是一个发明的轮子吗?#如果_opt(Option&opt,F F){…}包含
模板无效
FWIW,有一些std::optional
的实现可以与C++11一起使用。Ashared_ptr
因为这太过分了,对于if_opt
的std::function
也太过分了,因为它从来没有被存储过。@IgorTandetnik老实说,这就是我想要的。我觉得不只是这么做太傻了。我接受这个答案@克里斯:谢谢,我不知道std::optional你知道这是一个发明的轮子吗?#包括
template<class F,
std::conditional_t<true, bool,std::result_of_t<F&(T&)>> = true
>
friend void if_opt(Option<T>& opt, F&& f){
if (opt) f(*opt.m_value);
}