Search code examples
c++gccc++builderstdbind

Should std::bind require move constructor?


When I try the following code in GCC 6.3 (ideone.com), it compiles and prints "OK!". When I try the same code in C++ Builder 10.1, it fails to compile:

[bcc32c Error] tuple(110): no matching constructor for initialization of 'A'
  tuple(433): in instantiation of function template specialization 'std::_Tuple_val<A>::_Tuple_val<std::_Tuple_val<A> >' requested here
  File3.cpp(4): candidate constructor (the implicit copy constructor) not viable: no known conversion from 'std::_Tuple_val<A>' to 'const A' for 1st argument
  File3.cpp(4): candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided

Line 433 is tuple(_Myt&&) = default;.

#include <iostream>
#include <functional>

struct A {
    // Define destructor to delete default move constructor
    ~A() {}

    int a = 0;
};

void func(const A&)
{
    std::cout << "OK!" << std::endl;
}

int main() {
    A a;
    auto f = std::bind(&func, a);
    f();
}

In the code, I define destructor in class A so that no move constructor is implicitly defined. The class should still have implicitly defined default constructor and copy constructor. Documentation says "The arguments to bind are copied or moved", so I expected that having a copy constructor is enough for using bind.

What explains this difference between two compilers? It this implementation-defined behavior or am I using std::bind incorrectly here?

C++ Builder is using C++11 and Ideone is C++14, so could that explain the difference?


Solution

  • std::bind should copy all CopyConstructible parameters into its return value:

    The return type of std::bind holds a member object of type std::decay::type constructed from std::forward(f), and one object per each of args..., of type std::decay::type, similarly constructed from std::forward(arg_i).

    In this test case, it should be unnecessary for move constructors to be invoked. This looks like a bug in C++ Builder. I have filed a bug report: https://quality.embarcadero.com/browse/RSP-20209