From https://dlang.org/spec/cpp_interface.html:
"C++ constructors, copy constructors, move constructors and
destructors cannot be called directly in D code".
O RLY?
// hdr.hpp
struct Struct {
void *data;
Struct(int i);
Struct(const Struct&);
Struct(Struct&&);
~Struct();
int number() const;
};
// cpp.cpp
#include "hdr.hpp"
#include <iostream>
using namespace std;
Struct::Struct(int i) {
cout << " C++: int ctor " << i << endl;
data = new int(i);
}
Struct::Struct(const Struct& other) {
cout << " C++: copy ctor " << other.number() << endl;
data = new int(*reinterpret_cast<int*>(other.data));
}
Struct::Struct(Struct&& other) {
cout << " C++: move ctor " << other.number() << endl;
data = other.data;
other.data = nullptr;
}
Struct::~Struct() {
cout << " C++ dtor " << number() << endl;
delete reinterpret_cast<int*>(data);
}
int Struct::number() const {
return data == nullptr ? 0 :
*reinterpret_cast<int*>(data);
}
// ctors.dpp
#include "hdr.hpp"
import std.stdio;
void main() {
writeln("D: int ctor");
const cs = const Struct(2);
auto ms = Struct(3);
writeln;
writeln("D: copy ctor");
auto ccs = Struct(cs); assert(ccs.number() == 2);
auto cms = Struct(ms); assert(cms.number() == 3);
writeln;
writeln("D: move ctor");
auto tmp = Struct(4);
// dpp.move causes the move ctor be called instead of the
copy ctor
auto mv1 = Struct(dpp.move(tmp)); assert(mv1.number() ==
4);
// moved from, now T.init (even if the C++ code doesn't
do that)
assert(tmp.data is null);
// This last line doesn't work with dmd due to issue
18784.
// It works fine with ldc though.
auto mv2 = Struct(Struct(5)); assert(mv2.number() == 5);
writeln;
}
% clang++ -c cpp.cpp
% d++ --compiler=ldc2 ctors.dpp cpp.o -L-lstdc++
% ./ctors
D: int ctor
C++: int ctor 2
C++: int ctor 3
D: copy ctor
C++: copy ctor 2
C++: copy ctor 3
D: move ctor
C++: int ctor 4
C++: move ctor 4
C++ dtor 0
C++: int ctor 5
C++: move ctor 5
C++ dtor 0
C++ dtor 5
C++ dtor 4
C++ dtor 0
C++ dtor 3
C++ dtor 2
C++ dtor 3
C++ dtor 2
Atila