相关疑难解决方法(0)

currying和部分应用有什么区别?

我经常在互联网上看到各种各样的抱怨,其他人的currying例子并不是currying,但实际上只是部分应用.

我没有找到关于部分应用是什么的合理解释,或者它与currying有何不同.似乎存在普遍的混淆,在某些地方将等效的例子描述为currying,在其他地方描述为部分应用.

有人可以向我提供这两个术语的定义,以及它们如何区别的细节吗?

language-agnostic terminology definition currying partial-application

416
推荐指数
10
解决办法
5万
查看次数

"解包"一个元组来调用匹配的函数指针

我正在尝试存储std::tuple不同数量的值,这些值稍后将用作调用与存储类型匹配的函数指针的参数.

我创建了一个简化的示例,显示了我正在努力解决的问题:

#include <iostream>
#include <tuple>

void f(int a, double b, void* c) {
  std::cout << a << ":" << b << ":" << c << std::endl;
}

template <typename ...Args>
struct save_it_for_later {
  std::tuple<Args...> params;
  void (*func)(Args...);

  void delayed_dispatch() {
     // How can I "unpack" params to call func?
     func(std::get<0>(params), std::get<1>(params), std::get<2>(params));
     // But I *really* don't want to write 20 versions of dispatch so I'd rather 
     // write something like:
     func(params...); // Not legal
  }
}; …
Run Code Online (Sandbox Code Playgroud)

c++ function-pointers variadic-templates c++11 iterable-unpacking

251
推荐指数
6
解决办法
6万
查看次数

为"make_function"推断lambda或任意callable的调用签名

在某些情况下,希望能够键入 - 擦除可调用的(例如函数,函数指针,带有operator()lambda的对象实例mem_fn),例如在使用带有C++ 11 lambdas的Boost适配器中,其中可复制的和可默认构造的类型是必需的.

std::function将是理想的,但似乎没有办法自动确定用于实例化类模板的签名std::function.是否有一种简单的方法来获取任意可调用的函数签名和/或将其包装在适当的std::function实例化实例(即make_function函数模板)中?

具体来说,我正在寻找一个或另一个

template<typename F> using get_signature = ...;
template<typename F> std::function<get_signature<F>> make_function(F &&f) { ... }
Run Code Online (Sandbox Code Playgroud)

这样make_function([](int i) { return 0; })返回std::function<int(int)>.显然,如果一个实例可以使用多个签名(例如,具有多个,模板或默认参数operator()的对象)进行调用,那么预计这不会起作用.

尽管非过度复杂的非Boost解决方案是优选的,但Boost很好.


编辑:回答我自己的问题.

c++ lambda type-inference function c++11

26
推荐指数
1
解决办法
3945
查看次数

lambda被编译成什么类型​​?

据我所知,所有数据类型必须在编译时知道,而lambda不是一个类型.lambda被翻译成anonymous struct with operator()std::function包裹?

例如,

std::for_each(v.begin(), v.end(), [](int n&){n++;});
Run Code Online (Sandbox Code Playgroud)

c++ lambda c++11

18
推荐指数
3
解决办法
1936
查看次数

C++ 11中的"type-switch"构造

一直以来,我发现自己做了这样的事情:

Animal *animal = ...
if (Cat *cat = dynamic_cast<Cat *>(animal)) {
    ...
}
else if (Dog *dog = dynamic_cast<Dog *>(animal)) {
    ...
}
else { assert(false); }
Run Code Online (Sandbox Code Playgroud)

一旦我看到C++ 11中的闭包,我想知道,这样的事情可能吗?

Animal *animal = ...
typecase(animal,
    [](Cat *cat) {
        ...
    },
    [](Dog *dog) {
        ...
    });
Run Code Online (Sandbox Code Playgroud)

实现类型规划本来应该很容易,但我一直遇到一个问题,它无法弄清楚函数的参数,所以它无法知道尝试使用dynamic_cast,因为很难推断出lambdas的参数.花了几天的时间搜索谷歌和SO,但终于想通了,所以我将在下面分享我的答案.

c++ polymorphism lambda functional-programming c++11

11
推荐指数
1
解决办法
9699
查看次数

传递lambda函数作为参数时没有匹配的函数错误

我有一个数字列表.

我试图过滤列表,只保留正数.

我试图通过传递lambda作为参数来做到这一点.

我想知道为什么我会出现函数不匹配错误.

#include <vector>
#include <algorithm>
#include <functional>

template<typename T>
std::vector<T> keep(
        const std::vector<T> &original,
        std::function<bool(const T&)> useful)
{
    std::vector<T> out;
    for(T item:original)
    {
        if(useful(item))
            out.push_back(item);
    }
    return out;
}

int main()
{
    std::vector<int> a={4,6,2,-5,3,-8,13,-11,27};
    a=keep(a,[](const int& x)->bool{return x>0;});
    for(int y:a)
    {
        std::cout<<y<<std::endl;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是错误消息:

error: no matching function for call to ‘keep(std::vector<int>&, main()::<lambda(const int&)>)’
     a=keep(a,[](const int& x)->bool{return x>0;});
                                                 ^
Run Code Online (Sandbox Code Playgroud)

c++ lambda type-conversion c++11 callable-object

8
推荐指数
1
解决办法
6267
查看次数

使用std :: function参数重载运算符

我正在研究多种类型的地图持有者.它适用于所有原始类型,也适用于结构,例如Point.但是,如果我想将std :: function添加为另一个受支持的类型(用于回调),那么编译器会抱怨:

MT.cpp:426:15:没有可行的重载'='

MT.h:31:7:候选函数(隐式复制赋值运算符)不可行:第一个参数没有从'(lambda at MT.cpp:426:17)'到'const sharkLib :: MT'的已知转换

MT.h:31:7:候选函数(隐式移动赋值运算符)不可行:第一个参数没有从'(lambda at MT.cpp:426:17)'到'sharkLib :: MT'的已知转换

我实际上并不重载=运算符,而是[]使用每个受支持类型的专用构造函数重载.

.H

protected: 
    map<string,MT> valueMap;

public:
    MT (int value);
    MT (std::function<void(Ref*)> ccb);
    virtual MT& operator[] (const char* key);
Run Code Online (Sandbox Code Playgroud)

的.cpp

MT::MT (int value)
{
    this->type = ValueType::intValue;
    this->value.int_ = value;
}

MT::MT (std::function<void(Ref*)> value)
{
    this->type = ValueType::ccbValue;
    this->value.ccb_ = value;
}

MT& MT::operator[] (const char* key)
{
    return this->valueMap[key];
}
Run Code Online (Sandbox Code Playgroud)

用法

MT mt;

mt["int"] = 1;
mt["ccb"] = [](Ref *){ CCLOG("Pressed"); …
Run Code Online (Sandbox Code Playgroud)

c++ lambda overloading operator-overloading c++11

5
推荐指数
1
解决办法
602
查看次数

使用可变参数模板和lambda函数进行二进制搜索

想想这个,

struct Person {
    std::string name;
    Person (const std::string& n) : name(n) {}
    std::string getName(int, char) const {return name;}  // int, char play no role in this
        // simple example, but let's suppose that they are needed.
} *Bob = new Person("Bob"), *Frank = new Person("Frank"), *Mark = new Person("Mark"),
    *Tom = new Person("Tom"), *Zack = new Person("Zack");

const std::vector<Person*> people = {Bob, Frank, Mark, Tom, Zack};
Run Code Online (Sandbox Code Playgroud)

因为people按名称排序,我们可以执行二进制搜索以查找people具有特定名称的元素.我希望这个看起来像是这样的

Person* person = binarySearch (people, "Tom",
   [](Person* p, …
Run Code Online (Sandbox Code Playgroud)

c++ binary templates variadic c++11

3
推荐指数
1
解决办法
612
查看次数

接受lambda作为函数参数并提取返回类型

我需要接受lambda函数作为参数并找出它的返回类型.到目前为止,我无法想出任何可行的方法.这是一个例子:

template <typename T1, typename T2>
T1 foo(T2 arg, std::function<T1(T2)> f)
{
    return f(arg);
}

...

int n = foo(3, [](int a){ return a + 2; });   <-- ERROR!
Run Code Online (Sandbox Code Playgroud)

怎么做到呢?Boost解决方案也可以.

c++ lambda templates c++11

2
推荐指数
2
解决办法
509
查看次数

将重载函数转换为专用函数模板

我有一个当前为不同数据类型重载的函数,并使用lambda(函数指针)初始化这些数据类型.我正在将它们转换为模板实例但尚未成功.

这是重载版本 -

#include <iostream>
using namespace std;


void doSome(int (*func)(int &)){
    int a;
    a = 5;
    int res = func(a);
    cout << a << "\n";
}


void doSome(int (*func)(double &)){
    double a;
    a = 5.2;
    int res = func(a);
    cout << a << "\n";
}


int main() {
    doSome([](int &a){
        a += 2;
        return 1;
    });

    doSome([](double &a){
        a += 2.5;
        return 1;
    });
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

请注意,我已经采用了示例int并且double为了简化,它们可能是实际代码中的一些完全不同(和复杂)类型.


这是我尝试过的 -

#include <iostream>
using namespace std; …
Run Code Online (Sandbox Code Playgroud)

c++ lambda templates overloading c++14

2
推荐指数
1
解决办法
110
查看次数