将lambda表达式视为可调用对象的"语法糖",可以表达未命名的基础类型吗?
一个例子:
struct gt {
bool operator() (int l, int r) {
return l > r;
}
} ;
Run Code Online (Sandbox Code Playgroud)
现在,[](int l, int r) { return l > r; }是上述代码的优雅替代(加上gt的可调用对象的必要创建),但有没有办法表达gt(类型)本身?
一个简单的用法:
std::set<int, gt> s1; // A reversed-order std::set
// Is there a way to do the same using a lambda?
std::set<int, some-magic-here-maybe([](int l, int r) { return l > r; }) > s2;
Run Code Online (Sandbox Code Playgroud) 我正在尝试lambdas以及不同的lambda表达式具有不同类型的事实,即使它们是相同的.考虑这段代码
#include <iostream>
template <typename T> void once(T t){
static bool first_call = true;
if (first_call) t();
first_call = false;
}
int main() {
int counter = 0;
auto a = [&counter](){counter++;};
once(a);
once(a);
std::cout << counter; // 1
auto b = a; // same type
once(b);
std::cout << counter; // 1
auto c = [&counter](){counter++;}; // different type
once(c);
once(c);
std::cout << counter; // 2
}
Run Code Online (Sandbox Code Playgroud)
此打印112,即,a和b是相同类型的,当然和c具有不同的类型.
是否允许编译器使用c的类型与a …
我正在尝试编写一个包装器make_function,它std::make_pair可以std::function用合适的可调用对象创建一个对象.
就像make_pair对于函数指针一样foo,auto f0 = make_function(foo);创建一个正确类型签名的std::function函数对象f0.只是为了澄清,我不介意偶尔给出类型参数make_function,以防很难(或不可能)从参数中完全推断出类型.
到目前为止我提出的(下面的代码)适用于lambdas,一些函数指针和函子(我没有考虑挥发性).但我无法让它起作用std::bind或std::bind<R>结果.在下面的代码中
auto f2 = make_function(std::bind(foo,_1,_2,_3)); //not OK
Run Code Online (Sandbox Code Playgroud)
不会编译/工作,使用gcc 4.8.1.我猜测,我没有捕捉到operator()了bind正确的结果,但我不知道如何解决它.
任何有关如何解决此案例或改善其他角落案件的帮助表示赞赏.
当然,我的问题是如何修复下面示例中的错误.
对于后台,我可以在这个问题中找到我使用此包装器的一种情况:如何使C++ 11函数采用函数<>参数自动接受lambdas.如果您不批准使用std::function或以我的具体使用方式,请在该帖子中留下您的意见,并在此处讨论技术问题.
---编辑---
从一些评论中,我了解到这是因为模糊性问题(std::bind结果函数调用operator()的模糊性).正如@Mooing Duck的回答所指出的,解决方案是明确地给出参数类型.我已经更新了代码以结合@Mooing Duck的答案中的三个函数(稍微更改了类型参数),这样make_function包装器现在可以像以前一样处理/类型推导明确的情况,并允许指定完整类型签名歧义.
(我的明确案例的原始代码位于:https://stackoverflow.com/a/21665705/683218,可在以下网址进行测试:https://ideone.com/UhAk91):
#include <functional>
#include <utility>
#include <iostream>
#include <functional>
using namespace std;
// For …Run Code Online (Sandbox Code Playgroud) C++ 11同时具有lambda和std :: function <>,但不幸的是,它们有不同的类型.一个结果是,人们无法直接在高阶函数中使用lambda,例如lisp中的map.例如,在以下代码中
#include <vector>
#include <functional>
using namespace std;
template <typename A,typename B>
vector<B> map(std::function<B (A)> f, vector<A> arr) {
vector<B> res;
for (int i=0;i<arr.size();i++) res.push_back(f(arr[i]));
return res;
}
int main () {
vector<int> a = {1,2,3};
map([](int x) -> int { return x;},a); //not OK
auto id_l = [](int x) -> int { return x;};
map(id_l,a); //not OK;
function<int (int)> id_f = id_l;
map(id_f,a); //OK
return 0;
}
Run Code Online (Sandbox Code Playgroud)
,直接使用lambda作为main()的第2行将无法正常工作.g++ -std=c++11 testfunc.cpp返回`... testfunc.cpp:14:37:注意:'main():: __ lambda0'不是从'std …
所以想象我们有2个功能(void : ( void ) ),(std::string : (int, std::string))而且我们还可以有10个功能.所有(或其中一些)采用不同的参数类型,并可以返回不同的类型.我们想将它们存储在a中std::map,因此我们得到这样的API:
//Having a functions like:
int hello_world(std::string name, const int & number )
{
name += "!";
std::cout << "Hello, " << name << std::endl;
return number;
}
//and
void i_do_shadowed_stuff()
{
return;
}
//We want to be capable to create a map (or some type with similar API) that would hold our functional objects. like so:
myMap.insert(std::pair<std::string, fun_object>("my_method_hello", hello_world) )
myMap.insert(std::pair<std::string, fun_object>("my_void_method", i_do_shadowed_stuff) )
//And …Run Code Online (Sandbox Code Playgroud) 如何检查两个函数签名是否属于同一类型。这是我尝试过但没有编译
#include <iostream>
#include <type_traits>
#include <functional>
struct Employee {
int id;
int age;
Employee(const int id, const int age) {
this->id = id;
this->age = age;
}
void print() const {
std::cout << "ID: " << id << ", AGE: " << age << std::endl;
}
};
template<typename T, typename Comp>
const T& get_min_emp(const T& a, const T& b, Comp comp) {
static_assert(std::is_same<Comp, bool(*)(const T&, const T&)>::value, "invalid comparator");
return comp(a, b) ? a : b;
}
int main() …Run Code Online (Sandbox Code Playgroud)