我正在尝试为lambda函数创建类似bash的管道运算符重载,其中您将矢量传递给lambda,该lambda可以过滤或打印矢量
我尝试将auto与decltype一起使用,尝试将它们全部放在同一个函数中,希望auto知道何时返回void和何时返回向量,但我尝试执行的所有操作都不编译或说出模棱两可的重载。 / p>
这是代码,
#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; };
有什么提示吗?
答案 0 :(得分:1)
使用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
:观看Type trait to get element type of std::array or C-style array
顺便说一句,您不应该写using namespace std;
。