VC2013: function from bind not compiling
I would normally quote the standard, but the standardese here is particularly dense, so I'll just explain what's happening.
std::bind
does something special when you pass an argument to be bound if that argument is a function object returned by a previous call to std::bind
. Suppose you do:
auto f = std::bind(foo, std::placeholders::_1);
auto g = std::bind(bar, f, std::placeholders::_1);
Then invoking g(a)
is roughly equivalent to
bar(foo(a), a)
rather than
bar(f, a)
Demo.
That is, if you pass something returned by bind
to bind
as an argument to be bound, what's going to end up being passed to the function you are binding is the result of invoking that bind expression. It's a sort of composition.
However, in your code, you actually don't want the composition to take place. (This composition is what caused g++ to emit 320+ lines of errors when I tried to call your fn_gg
on an A
. Clang with libc++ printed only 10 lines, thankfully.) You want fn_g
to be treated just like an ordinary argument. So you can wrap it in a std::function
:
std::function<bool (const std::shared_ptr<S>&, A&)> fn_g = std::bind(getter, this, std::placeholders::_1, std::placeholders::_2);
C++ std::bind to std::function, what went wrong in VS2015?
Your function takes its argument by reference (double &
) while your are trying to assign it to the function with signature that takes by value (double
).
This has compiled in VS2013 most likely due to conformance bugs (maybe some weird interaction with non-const ref to temporary MSVC extension). Basically it's not a valid C++ code. VS2015 is leagues ahead of previous VSes (VS2017 is even more so) in terms of standard support and conformance so this faulty code is no longer compiling.
Anyway, std::bind is almost entirely obsoleted by lambdas, which should be supported by VS2010+. They produce better code, better warnings/errors, easier to write and debug.
For example, your code could'be rewritten like this:
std::function<double(double)> oFunc = [this](double x){ return myfunction(x); };
Or like this if you actually want to pass by reference:
std::function<double(double &)> oFunc = [this](double &x){ return myfunction(x); };
Notice how shorter and simpler it is.
VS2013 std::function with member function
std::function
is required to accept pointers to member functions (definition of INVOKE
).
The simplest workaround is to use std::mem_fn
instead, or wrap the constructor argument with std::mem_fn
:
std::function<void(const Foo&, int)> fun = std::mem_fn(&Foo::bar);
boost::fusion::invoke compiler error with Visual Studio 2013
I suspect the default for BOOST_RESULT_OF has changed for VS2013.
#define BOOST_RESULT_OF_USE_TR1
makes it compile. Chances are this bug is known and has been fixed in trunk, but you might want to report it still
Visual Studio 2013 C++ - Passing std::unique_ptr to a bound function
I had the same problem with VS 2012 recently. I believe this is a bug in MSVC; at least in MSVC++11 the pseudo-variadic expansion seems to forward the parameters by value to some internal function. Seems this hasn't been improved.
As a workaround, I'm using lambdas instead, but another hack is required to make it work:
std::function<void (std::unique_ptr<int>)> bound =
[] (std::unique_ptr<int> arg) { func(std::move(arg)); };
still doesn't compile. But if you add any captured value (even one that isn't used), it compiles:
int x;
std::function<void (std::unique_ptr<int>)> bound =
[x] (std::unique_ptr<int> arg) { func(std::move(arg)); };
std::function not compiling in VS2012
This looks like a bug in VS2012, I have made a bug report here.
For now the following works :
Edit: edited based on Xeo's suggestion to use std::mem_fn
#include <iostream>
#include <functional>
struct Foo {
Foo(int num) : num_(num) {}
void print_add(int i) const { std::cout << num_+i << '\n'; }
int num_;
};
int main()
{
// store a call to a member function
std::function<void(const Foo&, int)> f_add_display = std::mem_fn(&Foo::print_add);
Foo foo(314159);
f_add_display(foo, 1);
}
Related Topics
Why Do C++ Template Definitions Need to Be in the Header
How to Know the Right Max Size of Vector? Max_Size()? But No
How to Print the Address of Char Array
Enum Class Constructor C++ , How to Pass Specific Value
"_Gfortran_Pow_C8_I4" Error When Linking .O Files from G++ and Gfortran Using G++
C/C++: Casting Away Volatile Considered Harmful
Partially Truncating a Stream (Fstream or Ofstream) in C++
Is It Possible for the Executable to Ask for Administrator Rights? (Windows 7)
What Happen to Pointers When Vectors Need More Memory and Realocate Memory
Strange Behavior with Constexpr Static Member Variable
Can You Access Private Member Variables Across Class Instances
Breaking Out from Socket Select
C++ When Should We Prefer to Use a Two Chained Static_Cast Over Reinterpret_Cast