C++ 基于lambda参数重载函数模板
我正在尝试创建一个函数,在该函数中,调用者可以通过一组特定的已知参数传入lambda(返回类型可以是调用者想要的任何类型) 假设可能的lambda签名是C++ 基于lambda参数重载函数模板,c++,templates,overloading,C++,Templates,Overloading,我正在尝试创建一个函数,在该函数中,调用者可以通过一组特定的已知参数传入lambda(返回类型可以是调用者想要的任何类型) 假设可能的lambda签名是 T(小部件*) T(Widget2*) 我试过几件事,但都没能成功 struct Widget2{ int count = 0; }; class Widget { public: template<typename Fn, typename T = std::invoke_result_t<Fn, Widget*>
struct Widget2{
int count = 0;
};
class Widget {
public:
template<typename Fn, typename T = std::invoke_result_t<Fn, Widget*>>
T doIt(Fn&& fn)
{
return fn(_sibling);
}
template<typename Fn, typename T = std::invoke_result_t<Fn, Widget2*>>
T doIt(Fn&& fn)
{
return fn(_other);
}
private:
Widget* _sibling = nullptr;
Widget2* _other = nullptr;
};
struct Widget2{
整数计数=0;
};
类小部件{
公众:
模板
T doIt(Fn和&Fn)
{
返回fn(_同胞);
}
模板
T doIt(Fn和&Fn)
{
返回fn(_其他);
}
私人:
Widget*_sibling=nullptr;
Widget2*_other=nullptr;
};
我也试过这样做
template<typename Fn>
auto doIt(Fn&& fn)
{
if (std::is_invocable_v<Fn, Widget*>)
return fn(_sibling);
else if (std::is_invocable_v<Fn, Widget2*>)
return fn(_other);
}
模板
自动doIt(Fn&&Fn)
{
如果(标准::是否可发票)
返回fn(_同胞);
否则如果(标准::是否可发票)
返回fn(_其他);
}
编译器中的以下代码:
我宁愿避免添加多个函数,比如doItWidget1、doItWidget2等等
有没有一种方法可以基本上根据传入lambda的参数重载函数?如果可以使用
enable\u来消除错误的重载
template<typename Fn, std::enable_if_t<std::is_invocable_v<Fn, Widget*>, int> = 0>
auto doIt(Fn&& fn)
{
return fn(_sibling);
}
template<typename Fn, std::enable_if_t<std::is_invocable_v<Fn, Widget2*>, int> = 0>
auto doIt(Fn&& fn)
{
return fn(_other);
}
模板
自动doIt(Fn&&Fn)
{
返回fn(_同胞);
}
模板
自动doIt(Fn&&Fn)
{
返回fn(_其他);
}
请注意,您甚至不需要计算返回类型t
,只需使用auto
即可
这里有一个。Simpler:template std::invoke\u result\t>doIt(Fn&&Fn)
,它也会触发SFINAE,但更简单,不可绕过。或者template auto doIt(Fn&&Fn)->decltype(Fn(_sibling)){return Fn(_sibling);}
,或者template auto doIt(Fn&&Fn){return Fn(_sibling);}
,具体取决于您的编译器版本这是完美的。如果我在模板中显式指定了类型,我希望编译器能够找出它。我很好奇为什么template T doIt(Fn&&Fn)
失败了,但是用相同的值替换T是有效的std::invoke\u result\T doIt(…)
有效的。