1

Q1)鉴于我们有

typedef double (*function_t)(double);

或者

typedef std::function<double(double)> function_t;

我们如何定义

std::shared_ptr<function_t> ptr_func = ???

对于某些功能。

假设我们想要一个shared_ptr已经定义的对象(现在忘记它违背了目的 - 但我需要这个)。作为示例,请考虑以下类型的对象double

struct null_deleter
{
    void operator() (void const *) const {};
};

int main()
{
    // define object
    double b=0;

    // define shared pointer
    std::shared_ptr<double> ptr_store;
    ptr_store.reset(&b,null_deleter()); // this works and behaves how you would expect
}

虽然如果我们对 ashared_ptr类型做同样的事情function_t,即

double f (double x)
{
    // some_function + return
}

int main()
{

    // define shared pointer
    std::shared_ptr<function_t> ptr_store;
    ptr_store.reset(&f,null_deleter()); // ERROR: does not work
}

返回的错误类似于以下内容:

error: cannot convert 'double (*)(double)' to 'double (**)(double)' in initialization

或在std::function

error: cannot convert 'double (*)(double)' to 'std::function<double(double)>*' in initialization

很明显没有传递正确的类型,可能我们不允许这样做(?)

注意:使用windows MinGW 上的g++4-7-2版本编译-std=c++11 -O3

几个答案效果很好,我会在今天的某个时候回复大家。现在是早上6.30,我还没睡。我正在实施的整个设计模式可能是错误的,希望我能稍后解释一下:|

4

2 回答 2

0

这是人为的,但是在不了解您实际上要做什么的情况下,这是我能想到的最好的方法:

#include <iostream>

typedef std::function<double(double)> function_t;

double f(double t)
{
    return t*5;
}

int main(int argc, char*argv[])
{
    // You usually want to attach the shared pointer to a dynamically allocated object
    std::shared_ptr<function_t> ptr;
    ptr.reset(new function_t(std::bind(&f, std::placeholders::_1)));
    std::cout << (*ptr)(5.0);

    // But we can attach the smart pointer to a local function object on the stack (BAD IDEA)
    function_t fff = std::bind(&f, std::placeholders::_1);
    ptr.reset(&fff);
    std::cout << (*ptr)(5.0);
}
于 2013-03-27T05:13:48.483 回答
0

我尽量避免使用原始函数指针,并且更喜欢将它们包装在函数对象中。按照这种方法,下面的代码可以工作。shared_ptr想要包含一个指向作为其第一个模板参数给出的类型的对象的指针,所以如果你使用

std::shared_ptr<function_t>

那么它必须包含一个

function_t*

你说得对。

通常,我们会传入一个指向动态分配对象的指针,如

std::shared_ptr<function_t> ptr_store( new function_t( f ) );

但在您的情况下,您想传递已经在堆栈上的对象的地址。

所以我创建了一个function_t名为 的本地对象foo,然后将它的地址连同它一起传递null_deleter给 shared_ptr,一切正常。

我希望这有帮助!

PS 我用的是 Microsoft Visual Studio 2010

#include <functional>
#include <memory>
#include <iostream>

typedef std::function<double(double)> function_t;

struct null_deleter
{
  void operator() (void const *) const {};
};

double f (double x)
{
  return 2.0 * x;
}

int main( int argc, char* argv[] )
{
  // A function object on the stack
  function_t foo( f );

  // Putting this in a local scope to verify that when the shared_ptr goes
  // out of scope, nothing bad happens.
  double result1;
  {
  std::shared_ptr<function_t> ptr_store;
  ptr_store.reset( &foo, null_deleter() );

  result1 = (*ptr_store)( 10.0 );
  std::cout << result1 << std::endl;
  }
  // ptr_store has now been destroyed

  // Calling the foo function object again just to be sure it's still OK
  double result2 = foo( 5.0 );
  std::cout << result2 << std::endl;
}
于 2013-03-27T05:40:37.293 回答