c++ - 为什么没有 std::make_function()?

标签 c++ function c++11

std::function<>是几乎所有可调用事物的有用包装器,包括自由函数、lambda、仿函数、成员函数,结果来自 std::bind .但是,当创建 std::function<> ,必须明确指定函数签名,如 (取自here)

struct Foo {
    Foo(int num) : num_(num) {}
    void print_add(int i) const { std::cout << num_+i << '\n'; }
    int num_;
};

void print_num(int i)
{ std::cout << i << '\n'; }

struct PrintNum {
    void operator()(int i) const
    { std::cout << i << '\n'; }
};

// store a free function
std::function<void(int)> f_display = print_num;

// store a lambda
std::function<void()> f_display_42 = []() { print_num(42); };

// store the result of a call to std::bind
std::function<void()> f_display_31337 = std::bind(print_num, 31337);

// store a call to a member function
std::function<void(const Foo&, int)> f_add_display = &Foo::print_add;

// store a call to a member function and object
using std::placeholders::_1;
std::function<void(int)> f_add_display2= std::bind( &Foo::print_add, foo, _1 );

// store a call to a member function and object ptr
std::function<void(int)> f_add_display3= std::bind( &Foo::print_add, &foo, _1 );

// store a call to a function object
std::function<void(int)> f_display_obj = PrintNum();

即使签名可以从分配的对象中推断出来。似乎避免这种情况的一种自然方法(在大量模板化的代码中应该非常方便)是重载函数模板 make_function (在精神上类似于 std::make_pairstd::make_tuple ),当上面的例子简单地变成

// store a free function
auto f_display = make_function(print_num);

// store a lambda
auto f_display_42 = make_function([](){ print_num(42);});

// store the result of a call to std::bind
auto f_display_31337 = make_function(std::bind(print_num, 31337));

// store a call to a member function
auto f_add_display = make_function(&Foo::print_add);

// store a call to a member function and object
using std::placeholders::_1;
auto f_add_display2 = make_function(std::bind( &Foo::print_add, foo, _1));

// store a call to a member function and object ptr
auto f_add_display3 = make_function(std::bind( &Foo::print_add, &foo, _1));

// store a call to a function object
auto f_display_obj = make_function(PrintNum());

另一个可能的用例是获取任何类型的可调用对象的返回类型

decltype(make_function(function_object))::return_type;

避免 Piotr S. 对 this question 的回答中的特质魔法.

那么,我的问题是:为什么标准不提供此功能?可以make_function在没有编译器魔法的情况下实现?还是需要编译器魔法? (即便如此,第一个问题仍然存在。)

最佳答案

class multi_functor
{
  public:
    void operator()(int) { std::cout << "i'm int" << std::endl }
    void operator()(double) { std::cout << "i'm double" << std::endl }
};

int main(void)
{
  auto func = make_function(multi_functor());
}

因为这里 func 的类型是什么?

这种歧义适用于所有仿函数对象(包括 bind 返回值和 lambdas),这将使 make_function 仅可用于函数指针。

关于c++ - 为什么没有 std::make_function()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27825559/

相关文章:

c++ - DEFPUSHBUTTON 不将焦点默认为 IDCANCEL

c++ - 抛出异常是否影响errno或设置最后一个错误码

c++ - 尝试使用合并函数对链表进行排序?

matlab - 如何编写一个创建和存储变量的函数?

c++ - 为什么 Visual C++ 无法编译继承自私有(private)嵌套类的友元模板?

c - 当函数的返回类型不允许我这样做时,如何在 C 中返回错误代码?

c++ - 错误 : &P cannot be used as a function

c++ - clang-format noop .clang-格式文件

c++ - 循环 std::unordered_map,序列总是我插入元素的序列?

templates - 为什么在 C++0x 中,编译器选择通用移动赋值而不是特定移动赋值?