The following code does not compile GCC 6.1, but works in Clang 3.8.0and Visual Studio 2015:
#include <memory>
class base {
public:
base(std::unique_ptr<int>) {}
};
class derived : public base {
public:
using base::base;
};
int main() {
derived df(std::make_unique<int>());
}
With the following errors:
main.cpp: In constructor 'derived::derived(std::unique_ptr<int>)':
main.cpp:10:17: error: use of deleted function
'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&)
[with _Tp = int; _Dp = std::default_delete<int>]'
using base::base;
^~~~
In file included from /usr/local/include/c++/6.1.0/memory:81:0,
from main.cpp:1:
/usr/local/include/c++/6.1.0/bits/unique_ptr.h:356:7: note: declared here
unique_ptr(const unique_ptr&) = delete;
^~~~~~~~~~
main.cpp: In function 'int main()':
main.cpp:14:39: note: synthesized method 'derived::derived(std::unique_ptr<int>)'
first required here
derived df(std::make_unique<int>());
It seems to be trying to call the remote copy constructor, but this works just fine:
void foo(std::unique_ptr<int>) {}
int main() {
foo(std::make_unique<int>());
}
And this example with -fno-elide-constructorsoutputs move called.:
struct move_only {
move_only() { std::cout << "default called."; }
move_only(move_only&&) { std::cout << "move called."; }
};
void foo(move_only) { }
int main() {
foo(move_only{});
}
I understand that the two situations are not identical, but it seems strange that it &&takes to make an example of an inherited constructor, and not the last. As a health check, explicitly executing move_only(const move_only&) = delete;and changing the signature to void foo(const move_only&) { }is still compiled, except that the move constructor is not even called (possibly, possibly).
12.6.3 from the last draft of the standard states:
1 B D ( , ([namespace.udecl])), D , , , B- . ; , D. [:
struct B1 {
B1(int, ...) { }
};
struct D1 : B1 {
using B1::B1;
int x;
};
void test() {
D1 d(2, 3, 4);
}
, foo(move_only) ?