Unique_Ptr Compile Error

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



Leave a reply



Submit