The following code compiles with clang 3.0/libc++:
#include <memory>
class Foo
{
public:
Foo()
: mem_(new int(10))
{
}
std::unique_ptr<int> mem_;
};
int main()
{
auto foo = std::make_shared<Foo>();
return 0;
}
But this one doesn't (std::string
parameter added):
#include <memory>
#include <string>
class Foo
{
public:
Foo(const std::string& s)
: mem_(new int(10))
{
}
std::unique_ptr<int> mem_;
};
int main()
{
auto foo = std::make_shared<Foo>("aaa");
return 0;
}
Clang complains about the usage of a deleted constructor. To me, this makes no sense, since std::make_shared
isn't supposed to copy the Foo instance, the only thing that would trigger the call to the (deleted) copy constructor of std::unique_ptr
.
But lo and behold, as soon as I define a move constructor explicitly, it compiles.
#include <memory>
#include <string>
class Foo
{
public:
Foo(const std::string& s)
: mem_(new int(10))
{
}
Foo(Foo&& other)
: mem_(std::move(other.mem_))
{
}
std::unique_ptr<int> mem_;
};
int main()
{
auto foo = std::make_shared<Foo>("aaa");
return 0;
}
Now, questions:
std::make_shared
copy/move the object while constructing it?EDIT: Checked and all examples appear to compile fine with gcc 4.5.1 (via ideone.com), I suspect it's the case of a clang/libc++ bug, but questions 2 and 3 still stand, plus I'd like to know which compiler is more "correct".
Why does it compile in the first example but not the second?
This is a libc++ bug. I am working on a fix for it now...
Can std::make_shared copy/move the object while constructing it?
No, I don't believe it can.
Why does adding a move constructor fix the problem? I don't recall that adding non-default constructor should suppress an implicit move constructor.
In the version of clang you're using, implicit move constructors are not implemented yet.
Update
Fixed: http://llvm.org/bugs/show_bug.cgi?id=11616
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With