1

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?

VLL
  • 9,634
  • 1
  • 29
  • 54
  • 1
    isn't C++ builder broken for years already? In deed, in `std::bind(..., a)` `a` is _copied_ into the data-member variable in the object created by `bind`. No move constructor is needed. In fact, `std::bind` existed before move semantics ;) – YSC Mar 27 '18 at 08:58
  • Quite difficult to find compatibility information on c++builder. Which architecture are you working on ? – UmNyobe Mar 27 '18 at 09:04
  • I think you could find a simpler mcve. Try and make a `std::tuple` copy without invoking `bind`. – YSC Mar 27 '18 at 09:07
  • @UmNyobe I am working on 32-bit Windows, using BCC32C compiler: http://docwiki.embarcadero.com/RADStudio/Berlin/en/BCC32C – VLL Mar 27 '18 at 09:07
  • As far as I can see the code is correct. The error must be due to a bug in C++ builder or its standard library. – Johan Mar 27 '18 at 09:13
  • In recent versions of C++Builder, [BCC32C](http://docwiki.embarcadero.com/RADStudio/en/BCC32C) is a Clang-based C++11 compiler, and the [STL for BCC32C](http://docwiki.embarcadero.com/RADStudio/en/STL) is Dinkumware 6.50. Are you guys suggesting that either Clang or Dinkumware are broken in this matter? – Remy Lebeau Mar 27 '18 at 20:30
  • @Ville-ValtteriTiittanen give this a try [bds 2006 C hidden memory manager conflicts](https://stackoverflow.com/a/18016392/2521214) it will most likely not help as you got much different compiler but trying is for free just in case. – Spektre Mar 28 '18 at 08:30

1 Answers1

0

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

VLL
  • 9,634
  • 1
  • 29
  • 54
  • I am just curious did you try the constructors from my linked QA? Your answer sounds very similar to mine problems I solved with those... – Spektre Mar 31 '18 at 09:09
  • @Spektre I don't see what your QA has to do with this problem. Do you know what a move constructor is? I can make a move constructor with `A(A&&) = default;`. But I don't want to make a move constructor, I want compiler to resolve them implicitly. – VLL Apr 02 '18 at 09:58
  • If you see the solution in the answer adding empty constructors/destructors solved/bypassed a lot of hidden/unrelated errors of the compiler (both runtime and some compile errors too) for good. Adding move constructor sound pretty similar to that ... at least to me hinting it might be similar or the same bug of the compiler. – Spektre Apr 02 '18 at 10:42