Calling std :: functions

I am trying to write a class template that will take two std::function

in a constructor parameter and call them on RAII style construction and destruction.

What am I missing?

template <class T>
class HelloGoodbye{
public:
HelloGoodbye(std::function<T> const & f, std::function<T> const &g)
  :mf(f),mg(g)
{
  mf();
}


~HelloGoodBye()
{
  mg();
}

private:
std::function<T> mf;
std::function<T> mg;
};


class Printer
{
    public:
    void hello()
    {
        std::cout << "hello!" << std::endl;
    }
    void goodbye()
    {
        std::cout << "Goodbye!" << std::endl;   
    }
};

int main()
{
      Printer p;
      auto hi = std::bind(&Printer::hello, &p);
      auto bye = std::bind(&Printer::goodbye, &p);
      HelloGoodbye hgb(hi,bye);      
}

      

+3


source to share


2 answers


HelloGoodbye

is a class template, you need to specify the template argument when using it. eg.

HelloGoodbye<void()> hgb(hi,bye);   

      



LIVE

BTW: I guess that's ~HelloGoodBye()

a typo ~HelloGoodBye()

.

+3


source


You can specify the template type hgb

as suggested by songyuanyao, or you can create a make function

template <typename T>
HelloGoodbye<T> makeHG (std::function<T> const & hi,
                        std::function<T> const & bye)
 { return { hi, bye }; }

      

and using auto

, you can initialize hgb

like this

auto hgb = makeHG(hi, bye);

      



Unfortunately std::bind

- a strange beast with a return value of undefined, so you cannot pass the type returned from std::bind

to makeHG()

to get type inference T

.

So, if you want to use makeHG()

, you can use auto

to define hi

and bye

, but you must specify the type like this

  std::function<void()> hi = std::bind(&Printer::hello, &p);
  std::function<void()> bye = std::bind(&Printer::goodbye, &p);

      

So, I believe sonyuanyao is the best solution.

0


source







All Articles