标签: std-function

矢量std ::功能与不同的签名

我有许多具有不同签名的回调函数.理想情况下,我想将它们放在一个向量中,并根据某些条件调用适当的一个.

例如

void func1(const std::string& value);

void func2(const std::string& value, int min, int max);

const std::vector<std::function<void(std::string)>> functions
{
    func1,
    func2,
};
Run Code Online (Sandbox Code Playgroud)

我意识到上述情况是不可能的,但我想知道是否有任何我应该考虑的替代方案.我还没有找到任何东西,我已经尝试过,std::bind但没有成功实现我想要的东西.

这样的事情可能吗?

c++ stdvector c++11 std-function

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

从具有按值捕获的 lambda 移动构造 std::function 时调用两次移动构造函数

当移动-构造std::function从一个对象的λ,其中该拉姆达具有由值捕获,看来该物体的移动,构造函数,是值捕获被调用两次。考虑

#include <功能>
#include <iostream>

结构体
{
    整数值 = 1;

    Foo() = 默认值;

    Foo(const Foo &) {}

    富(富&&)
    {
        std::cout << "移动构造函数" << std::endl;
    }
};

int main()
{
    福福;
    自动 lambda = [=]() { 返回 foo.value; };
    std::cout << "---------" << std::endl;
    std::function<int()> func(std::move(lambda));
    std::cout << "---------" << std::endl;
    返回0;
}

输出是

---------
move ctor
move ctor
---------
Run Code Online (Sandbox Code Playgroud)

我在 Mac OS X Catalina 上工作,我的编译器是

g++-9 (Homebrew GCC 9.3.0) 9.3.0
Run Code Online (Sandbox Code Playgroud)

我用g++ -std=c++17. …

c++ lambda move-semantics std-function c++17

14
推荐指数
1
解决办法
663
查看次数

为什么std :: function实例有一个默认的构造函数?

这可能是一个哲学问题,但我遇到了以下问题:

如果您定义了一个std :: function,并且没有正确初始化它,那么您的应用程序将崩溃,如下所示:

typedef std::function<void(void)> MyFunctionType;
MyFunctionType myFunction;
myFunction();
Run Code Online (Sandbox Code Playgroud)

如果函数作为参数传递,如下所示:

void DoSomething (MyFunctionType myFunction)
   {
   myFunction();
   }
Run Code Online (Sandbox Code Playgroud)

然后,当然,它也崩溃了.这意味着我被迫添加这样的检查代码:

void DoSomething (MyFunctionType myFunction)
   {
   if (!myFunction) return;
   myFunction();
   }
Run Code Online (Sandbox Code Playgroud)

需要这些检查让我回到旧的C日,你还必须明确检查所有指针参数:

void DoSomething (Car *car, Person *person)
   {
   if (!car) return;      // In real applications, this would be an assert of course
   if (!person) return;   // In real applications, this would be an assert of course
   ...
   }
Run Code Online (Sandbox Code Playgroud)

幸运的是,我们可以在C++中使用引用,这阻止我编写这些检查(假设调用者没有将nullptr的内容传递给函数:

void DoSomething (Car &car, Person &person)
   {
   // I can assume that …
Run Code Online (Sandbox Code Playgroud)

c++ std-function

13
推荐指数
4
解决办法
1万
查看次数

从std :: function调用签名中减去模板参数

考虑这个模板功能:

template<typename ReturnT>
ReturnT foo(const std::function<ReturnT ()>& fun)
{
    return fun();
}
Run Code Online (Sandbox Code Playgroud)

为什么编译器不能ReturnT从传递的调用签名中推断出来?

bool bar() { /* ... */ }

foo<bool>(bar); // works
foo(bar); // error: no matching function call
Run Code Online (Sandbox Code Playgroud)

c++ templates std-function template-argument-deduction

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

C++ 11 std :: function和完美转发

为什么在C++标准中定义std :: function <> :: operator()是:

R operator()(ArgTypes...) const;
Run Code Online (Sandbox Code Playgroud)

并不是

R operator()(ArgTypes&&...) const;
Run Code Online (Sandbox Code Playgroud)

有人会认为要正确转发参数,我们需要&&然后std::forward<ArgTypes>...在转发呼叫时在函数体中使用?

我部分重新实现了std :: function来测试这个,我发现如果我使用&&,当我稍后尝试通过值将参数传递给operator()时,我从g ++中得到"无法将'xxx'左值'绑定到'xxx &&'" .我认为我对rvalue/forwarding概念有了足够的把握,但我还是不能理解这一点.我错过了什么?

c++ perfect-forwarding c++11 std-function

13
推荐指数
1
解决办法
2539
查看次数

只返回传递值的默认函数?

作为一个懒惰的开发人员,我喜欢使用这个技巧来指定一个默认函数:

template <class Type, unsigned int Size, class Function = std::less<Type> >
void arrange(std::array<Type, Size> &x, Function&& f = Function())
{
    std::sort(std::begin(x), std::end(x), f);
}
Run Code Online (Sandbox Code Playgroud)

但是在一个非常特殊的情况下我遇到了一个问题,如下所示:

template <class Type, unsigned int Size, class Function = /*SOMETHING 1*/>
void index(std::array<Type, Size> &x, Function&& f = /*SOMETHING 2*/)
{
    for (unsigned int i = 0; i < Size; ++i) {
        x[i] = f(i);
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我希望默认函数相当于:( [](const unsigned int i){return i;}一个只返回传递值的函数).

为了做到这一点,我需要写什么而不是/*SOMETHING 1*//*SOMETHING 2*/

c++ lambda templates c++11 std-function

13
推荐指数
1
解决办法
5250
查看次数

是否可以允许一个std :: function类型接受具有不同签名的lambdas

我有一个更高阶的函数map,类似于STL for_each,并将一个std::function对象映射vector到一些东西上.

template<class T, class U>
vector<U> map(function<U (T)> f, vector<T> xs) {
  vector<U> ret;
  for (auto &x: xs)
    ret.push_back(f(x));
  return ret;
}
Run Code Online (Sandbox Code Playgroud)

现在,我想有这样的高阶功能拍摄的类型两个对象function<int (const vector<T>&)>function<int (vector<T>)>,如所附小例子.

问题是,function<int (const vector<T>&)>并且 function<int (vector<T>)>似乎可以相互转换(请参阅headhead2),但map不会采用const引用版本function<int (const vector<int>&)>(请参阅参考资料Q1).

可以map通过显式转换(Q2)来接受const引用版本,但这很麻烦.

我想知道,一般来说,是否可以编写一个deref删除const引用的函数function<int (const vector<T>&)>并返回一个function<int (vector<T>)>

(如果可以,那么我将不必为const refs编写两个相同的重载/ map实现).

谢谢.

#include <vector>
#include …
Run Code Online (Sandbox Code Playgroud)

c++ c++11 std-function

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

C++ std :: function-like模板语法

在C++ 11中,您可以像这样实例化std :: function:

std::function<void(int)> f1;
std::function<int(std::string, std::string)> f2;
//and so on
Run Code Online (Sandbox Code Playgroud)

但是虽然网上有大量关于可变参数模板的信息,但我找不到任何关于如何编写std :: function-like模板的文章,这些模板会接受带括号的参数.任何人都可以解释一下语法及其局限性,或者至少指出现有的解释吗?

syntax templates variadic-templates c++11 std-function

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

传递非泛型函数的最有效方法是什么?

我正在学习C++中的函数式编程.我的目的是将非泛型函数作为参数传递.我知道模板方法,但是我想将函数签名限制为API设计的一部分.我在cpp.sh上编写了4个不同的方法示例:

// Example program
#include <iostream>
#include <string>
#include <functional>

typedef int(functor_type)(int);


int by_forwarding(functor_type &&x)  {
    return x(1);
}

int functor_by_value(functor_type x) {
    return x(1);
}

int std_func_by_value(std::function<functor_type> x) {
    return x(1);
}

int std_func_by_forwarding(std::function<functor_type> &&x) {
    return x(1);
}

int main()
{
    std::cout << functor_by_value([](int a){return a;}); // works
    std::cout << std_func_by_value([](int a){return a;}); // works
    std::cout << std_func_by_forwarding(std::move([](int a){return a;})); // works

    //std::cout << by_forwarding([](int a){return a;}); // how to move lambda with forwarding …
Run Code Online (Sandbox Code Playgroud)

c++ function functor std-function

13
推荐指数
4
解决办法
878
查看次数

为什么 C++23 std::move_only_function 没有推导指南?

C++23 引入了std::function的表兄弟std::move_only_function,就像它的名字一样,它是仅移动可调用对象的仅移动包装器(演示):

#include <functional>
#include <memory>

int main() {
  auto l = [p = std::make_unique<int>(0)] { };
  std::function<void(void)>           f1{std::move(l)}; // ill-formed
  std::move_only_function<void(void)> f2{std::move(l)}; // well-formed
}
Run Code Online (Sandbox Code Playgroud)

但与 不同的是std::function,该标准没有为其定义推导指南(演示):

#include <functional>

int func(double) { return 0; }
int main() {
  std::function f1{func};           // guide deduces function<int(double)>
  std::move_only_function f2{func}; // deduction failed
}
Run Code Online (Sandbox Code Playgroud)

禁止 CTAD 有理由吗?

c++ std-function c++17 c++23

13
推荐指数
1
解决办法
2328
查看次数