我不知道這是因爲一個好主意,作爲molbdnilo提到,你不會短路在我看來,代碼會誤導讀者。
無論如何,std::function
是一個昂貴的抽象,應該避免在這裏,因爲你不需要它的功能。
使用模板函數和std::enable_if
將工作:
template <typename T>
using returns_bool_when_called_with_int =
std::is_same<decltype(std::declval<T&>()(std::declval<int>())), bool>;
template <typename T0, typename T1>
using lambda_and_enabler = std::enable_if_t
<
returns_bool_when_called_with_int<T0>{} &&
returns_bool_when_called_with_int<T1>{}
>;
template <typename T0, typename T1, typename = lambda_and_enabler<T0, T1>>
auto operator&&(T0 lhs, T1 rhs)
{
// Note that `lhs` and `rhs` are being captured by copy.
// See the note at the end of the post for a more general alternative.
return [=](auto x){ return lhs(x) && rhs(x); };
}
以上可作爲代碼如下:
int main()
{
auto l0 = [](int x){ return x % 3 == 0; };
auto l1 = [](int x){ return x % 2 == 0; };
auto l_and = l0 && l1;
assert(l_and(6));
assert(!l_and(5));
assert(!l_and(4));
}
wandbox example
注:您可能想要perfect forward將您的lhs
和rhs
轉換爲由operator&&
返回的lambda,以避免不必要的副本和支持參考語義。我最近寫了一篇文章:"capturing perfectly-forwarded objects in lambdas"。然後
你的通用operator&&
功能會是這個樣子:
template <typename T0, typename T1,
typename = lambda_and_enabler<std::decay_t<T0>, std::decay_t<T1>>>
auto operator&&(T0&& lhs, T1&& rhs)
{
return [lhs = FWD_CAPTURE(lhs), rhs = FWD_CAPTURE(rhs)](auto&& x) mutable
{
return access(lhs)(x) && access(rhs)(x);
};
}
你不能說出一個lambda的類型,而且每一個都有一個獨特的類型。而且你可能不想重載'&&',因爲你不會得到預期的短路行爲。 – molbdnilo