unique_ptr compile error
This is just a guess.
Most likely you compiled your program like this (or similarly) :
g++ main.cpp
If you did, then the problem is that g++ uses c++03 as default. To use c++11 features (and std::unique_ptr
), you need to use newer version of c++ :
g++ -std=c++11
or
g++ -std=c++14
and I would recommend to use also -Wall -Wextra -pedantic
.
C++ unique_ptr; Why this sample codes get compile error?? error codes are so long that I can't specify it
There is no operator <<
for an object of the type std::unique_otr
.
If you need to output the value of the owned pointer then write
cout << "smart pointer 1: " << p1.get() << '\n';
If the template argument of the class template std::unique_ptr
is char
then you need to cast the returned expression of the member function get
to the type void *
. For example
cout << "smart pointer 1: " << static_cast<void *>( p1.get() ) << '\n';
Here is a demonstrative program.
#include <iostream>
#include <memory>
int main()
{
std::unique_ptr<int> p1(new int( 10 ) );
std::unique_ptr<char> p2( new char( 'A') );
std::cout << "smart pointer 1: " << p1.get() << '\n';
std::cout << "smart pointer 2: " << static_cast<void *>( p2.get() ) << '\n';
}
The program output might look like
smart pointer 1: 0x5593824d6e70
smart pointer 2: 0x5593824d6e90
If the owned pointer of an object of the type std::unique_ptr<char>
is outputted without casting then it will be outputted as a C string instead of outputting its stored value (address).
If you need to output the pointed value of an object of the class template std::unique_ptr
then just apply the dereference operator.
For example
cout << "smart pointer 1: " << *p1 << '\n';
Here is a demonstrative program
#include <iostream>
#include <memory>
int main()
{
std::unique_ptr<int> p1(new int( 10 ) );
std::unique_ptr<char> p2( new char( 'A') );
std::cout << "the value of the smart pointer 1: " << *p1 << '\n';
std::cout << "the value of the smart pointer 2: " << *p2 << '\n';
}
The program output is
the value of the smart pointer 1: 10
the value of the smart pointer 2: A
Before outputting a pointed value you can check whether the object of the class template std::unique_ptr
does not store a null pointer like
if ( p1 )
{
std::cout << "the value of the smart pointer 1: " << *p1 << '\n';
}
if ( p2 )
{
std::cout << "the value of the smart pointer 2: " << *p2 << '\n';
}
error with vector, unique_ptr, and push_back
push_back
expects an std::unique_ptr
, when passing raw pointer like new Square
, which is considered as copy-initialization, the raw pointer needs to be converted to std::unique_ptr
implicitly. The implicit conversion fails because std::unique_ptr
's conversion constructor from raw pointer is marked as explicit
.
emplace_back
works because it forwards arguments to the constructor of std::unique_ptr
and construct element in direct-initialization form, which considers explicit
conversion constructors.
The arguments args... are forwarded to the constructor as
std::forward<Args>(args)...
.
Compile error with gcc when in-class initializing unique_ptr of incomplete type to nullptr
The program, and the default member initialiser in particular, is well-formed. If a compiler refuses to compile, then it is a bug in the compiler as far as I can tell.
I can reproduce the problem with GCC 9.1 but not 9.2 nor trunk, so it appears to have been fixed. With older versions, you may need to give up using the default member initialiser as a workaround.
Compile error associated with std::unique_ptr and abstract classes
There are several typos in your code:
In Base
:
Change
initBase () { count = 0; }
to
Base () { count = 0; }
In Child
:
change
myClass(std::unique_ptr<Base> base) { _base(std::move(base)) };
to
myClass(std::unique_ptr<Base> base) : _base(std::move(base)) { }
change
~myClass() = default();
to
~myClass() = default;
In main()
:
change
myClass obj = myClass(std::make_unique<Child>());
to
myClass obj(std::make_unique<Child>());
#include <iostream>
#include <memory>
class Base {
public:
~Base () = default;
Base () { count = 0; }
virtual void method1() = 0;
virtual void method2() = 0;
private:
int count;
};
class Child final : public Base {
public:
Child() = default;
~Child() = default;
void method1() override { std::cout << "B Running method 1\n"; }
void method2() override { std::cout << "B Running method 2\n"; }
};
class myClass {
public:
myClass(std::unique_ptr<Base> base) : _base(std::move(base)) { }
~myClass() = default;
private:
std::unique_ptr<Base> _base;
};
int main() {
myClass obj(std::make_unique<Child>());
std::cout << "OK";
}
With those fixes in place, the code compiles fine.
Live Demo
Compile error trying to put a unique_ptr into a map
You cannot copy a unique_ptr
, because then it will not be unique. You have to move it - AddItem(std::move(someItem));
and myMap.emplace("test", std::move(item));
.
std::unique_ptr works in GCC but won't compile in Visual Studio
Your problem isn't std::unique_ptr
but std::vector
.
Your compiler comes with an old version of std::vector
that requires the element type to be copyable.
The return by value (return b;
) should invoke a move of the vector, but your std::vector
doesn't implement move.
std::unique_ptr
is moveable but not copyable, therefore it doesn't meet the pre-C++11 requirements for being used in std::vector
... a requirement which still applies to VC++ 2012.
Your best option is to use a newer compiler and standard library. One that supports move semantics on std::vector
.
Otherwise you might make some progress by eliminating the copy of std::vector
, for example, by having MakeBox
fill in an output argument rather than returning a new object.
static void MakeBox(Box& b) { /* fill Things in b provided by caller */ }
That's probably an exercise in futility though, because whenever the vector needs to grow, it has to relocate the existing elements to new storage, and with incomplete move support, it will try to copy those.
Moving unique_ptr inside a lambda function gives me a compiler error on C++17
The issue is that lambda's operator ()
is declared const
and with the move you try to modify the unique pointer j
.
Declare it mutable via auto t = std::thread([j = std::move(job)]() mutable ...)
or pass the unique_ptr
as an argument to the lambda.
Unique_ptr usage for pimpl - doesn't compile even though destructor is declared
Any constructor definition (including the implicitly defined default constructor) potentially invokes the destructor of the types of all member objects of class type. The rationale for this is that if constructing a later member throws, the destructor of all previous members would need to be called. In the case of the last member, this is not strictly required, but the standard does not make this exception.
For example, if your class had been:
struct complete_type_with_throwing_constructor {
complete_type_with_throwing_constructor() { throw 0; }
};
struct Wrapper
{
class Impl;
~Wrapper();
std::unique_ptr<Impl> _impl;
complete_type_with_throwing_constructor x;
};
Then the implicit default constructor of Wrapper
would construct _impl
then destroy it after the default constructor of x
throws.
This is the reason why your code works if you explicitly declare your default constructor. This moves the definition to a point where the destructor of std::unique_ptr<Impl>
can be instantiated.
As for your second question, you are right that the code should still not work when adding the definition afterwards. It's just that compilers do not detect it, so they don't have an error.
Related Topics
Do C++11 Compilers Turn Local Variables into Rvalues When They Can During Code Optimization
Non-Type Variadic Function Templates in C++11
Extern "C" Linkage Inside C++ Namespace
Visual Studio Compiler Warning C4250 ('Class1':Inherits 'Class2::Member' via Dominance)
How to Read Input When Debugging in C++ in Visual Studio Code
Qtextedit with Different Text Colors (Qt/C++)
How to Resize an Image to a Specific Size in Opencv
Using Std::Variant with Recursion, Without Using Boost::Recursive_Wrapper
C++ Regular Expressions with Boost Regex
Std::Istream_Iterator<> with Copy_N() and Friends
How to Get a List Video Capture Devices Names (Web Cameras) Using Qt (Crossplatform)? (C++)
Floating Point to Binary Value(C++)
How to Find How Much Memory Is Shared Between Forked Process with Copy-On-Write in Linux
How to Calculate a Sha-512 Hash in C++ on Linux
How to Do Password Authentication for a User Using Ldap