如何通过返回类型区分两个 lambda 函数?

How to differentiate two lambda functions by their return type?

本文关键字:两个 lambda 函数 何通过 返回类型区      更新时间:2023-10-16

我正在尝试为 lambda 函数创建一个类似 bash 的管道运算符重载,在其中您将一个向量传递给过滤或打印向量的 lambda

我尝试将 auto 与 decltype 一起使用,尝试将它们全部放在同一个函数中,希望 auto 知道何时返回 void 以及何时返回向量,但我尝试的所有内容要么不编译,要么说模棱两可的重载。

这是代码,

#include <iostream>
#include <algorithm>
#include <functional>
#include <type_traits>
using namespace std;
void operator | ( auto& v, auto map ) {
for( auto x : v )
map( x );
}
template <typename T>
T operator | ( T& vet, auto map)  {
cout << "else" << endl;
T aux;
for ( auto x : vet) 
aux.push_back(x);
return aux;
}
int main () {
vector<int> v{1,2,3,4,5,6,7,8} ;
v | []( int x ) { return x % 2 == 0; } | [] ( int x ) { cout << x << endl; };
v | [] ( int x ) { cout << x << endl; };
return 0;
}

以下是发生的情况:

trabapply3.cc:25:6: error: ambiguous overload for ‘operator|’ (operand types are ‘std::vector<int>’ and ‘main()::<lambda(int)>’)
25 |    v | [] ( int x ) { cout << x << endl; };

有什么提示吗?

使用std::is_invocable_r/std::invoke_result_t

#include <iostream>
#include <algorithm>
#include <functional>
#include <type_traits>
#include <vector>
template<typename T>
using element_type_t = std::remove_reference_t<decltype(*std::begin(std::declval<T&>()))>;
template <typename T, typename MapFunc, std::enable_if_t<std::is_void_v<std::invoke_result_t<MapFunc, element_type_t<T>>>, std::nullptr_t> = nullptr>
void operator | (const T& v, MapFunc&& map ) {
for(auto&& x : v )
map( x );
}
template <typename T, typename MapFunc, std::enable_if_t<std::is_invocable_r_v<element_type_t<T>, MapFunc, element_type_t<T>>, std::nullptr_t> = nullptr>
T operator | (const T& vet, MapFunc&& map)  {
T aux;
for (auto&& x : vet) 
aux.push_back(map(x));
return aux;
}
int main () {
std::vector<int> v{1,2,3,4,5,6,7,8} ;
v | []( int x ) { return x % 2 == 0; } | [] ( int x ) { std::cout << x << std::endl; };
v | []( int x ) { std::cout << x << std::endl; };
return 0;
}

https://wandbox.org/permlink/33zSMBubghwEt4EF

注意:关于element_type_t:观察类型特征以获取 std::array 或 C 样式数组的元素类型

顺便说一句,你不应该写using namespace std;.