3

I'd like to use parameters pack, but find the problem. Some code:

template <typename Function, typename... Args>
auto f(Function func, Args... args) -> decltype(func(args...))
{
    auto f11 = std::bind(func, args...);
    f11();
}

void print(const char* string)
{
    std::cout << string << std::endl;
}

All of this works well:

    f([] (const char* additional, const char* more) {
        std::cout << "hello ( " << additional << ", " << more << " )" << std::endl;
    }, "additional text", "and one more");

    auto printFunction = std::bind(&print, std::placeholders::_1);

    printFunction("hello from print bind");

    f(print, "hello from print directly");

but if i would like to give std::function to parameters pack:

f([] (std::function<void(const char*)> printParamFunc) {
 printParamFunc("hello from print from std::function");
}, printFunction);

application no more compiles.

So, what the problem to use function as parameter in pack?

Thanks.

UPDATE: if change code of f to:

template <typename Function, typename... Args>
auto f(Function func, Args... args) -> decltype(func(args...))
{
    func(args...);
}

it works well, but i wouldn't like to execute this function here, i wanna create function and pass it like param.

UPDATE2: Code execution example: http://ideone.com/gDjnPq

UPDATE3: Clear code with compilation error: http://ideone.com/50z7IN

user1733773
  • 360
  • 2
  • 14
  • When asking about a compilation error, *always* include the full text of the error message. – Angew is no longer proud of SO Nov 07 '13 at 12:55
  • @Angew compile error is three screens of text – user1733773 Nov 07 '13 at 12:58
  • 1
    Then add the most important parts. Try to decipher it and read what it wants to say. Without the error nobody can help you. – Arne Mertz Nov 07 '13 at 13:01
  • 3
    Can you put together a http://sscce.org on something like ideone and add a link so we can see the resulting error messages? – Yakk - Adam Nevraumont Nov 07 '13 at 13:01
  • @Yakk have put it one ideone – user1733773 Nov 07 '13 at 13:10
  • The very first error message says you need to return from a function returning non-`void`. The function that returns `decltype(blah)` -- make it return something. Like `return f11();` – Yakk - Adam Nevraumont Nov 07 '13 at 13:46
  • @Yakk it is warning, and adding return statements have not fixed the problem :( – user1733773 Nov 07 '13 at 13:48
  • @user1733773: it is a very strong warning, and it is going to be painful... because if the return type is `void` then you should not return (very, very, annoying mistake in the C/C++ standard...) – Matthieu M. Nov 07 '13 at 14:02
  • 1
    You can make it work if instead of `auto`, give `printFunction` type `std::function`. I don't know why's that. The error message from clang suggests that it can't deduce the `_Result` type of bind expression. – jrok Nov 07 '13 at 14:42
  • @jrok yeah, it works with this fix... strange behavior. – user1733773 Nov 07 '13 at 14:59
  • The point of a http://sscce.org is to remove cruft that gets in the way of understanding what is going wrong. Your link is not a http://sscce.org while it contains random, useless cruft that gets in the way of understanding what is wrong. Remove the errors and warnings that have *nothing to do with your problem*, and make your code *as correct as you can*, and reduce it to *only the error*. Or follow the link about http://sscce.org I've posted 3 times now and read what you can do to help solve your problem. – Yakk - Adam Nevraumont Nov 07 '13 at 15:22
  • 2
    Here is a sscce for the above: http://ideone.com/50z7IN -- I do not yet know why it doesn't compile, but there it is! – Yakk - Adam Nevraumont Nov 07 '13 at 15:36
  • 1
    [Answer is here](http://stackoverflow.com/questions/10777421/stdbind-a-bound-function) Some specific of std::bind. – user1733773 Nov 08 '13 at 09:25

1 Answers1

0

I understand the situation a bit better now.

Problem can be retroduced by this code:

void print(const char* string)
{
    std::cout << string << std::endl;
}

int main(int argc, char ** argv)
{
    auto lambda = [] (std::function< void ( const char * ) > printParamFunc) {
        printParamFunc("hello from lambda!");
    };

    std::bind(lambda, std::bind(print, std::placeholders::_1))();
}

Nested std::bind trying to evaluate and fails with conversion _1 to const char *. It is specific of std::bind.

We need analogue of boost::bind::protect -- functor storing other functor -- and it is solve problem:

template <class F>
struct lazy_evaluate {
    typedef typename F::result_type T;

    explicit lazy_evaluate(F f) : f_(f) {}

    template <class... Args>
    T operator()(Args&&... args) 
    {
        f_(std::forward<Args>(args)...);
    }

private:
    F f_; 
};

template <class F>
lazy_evaluate<F> lazy(F f)
{
    return lazy_evaluate<F>(f);
}

nested std::bind now looks like:

std::bind(lambda, lazy(std::bind(print, std::placeholders::_1)))();

and works well.

user1733773
  • 360
  • 2
  • 14