Search code examples
c++pointersunique-ptr

Can a smart pointer be forward declared and initialized separately?


I'm trying to learn how to use smart pointers in Cpp, and I'm running into a roadblock; I want to declare my variables as say unique_ptr in one part of my code, possibly as a class member or part of a namespace, then initialize/"make_unique" elsewhere in my code. I've read quite a few questions about smart pointers, and incomplete type information, but I'm not sure I'm fully understanding. This is the last resource I read; Incomplete types and shared_ptr / unique_ptr

This is my toy code I'm trying to get working. 'v1' works as expected, on a single line. 'v2' Is what i'm trying to make work

std::unique_ptr<glm::vec3>v1 = std::make_unique<glm::vec3>(); //Works as expected
std::unique_ptr<glm::vec3>v2; //Declare a unique_ptr here, but i don't want to allocate any memory for it yet...

//do things i need to do before memory is allocated to v2

v2 = std::make_unique<glm::vec3>(); //...NOW I want to allocate memory for v2 and prepare it to be used

These are the errors i get from VS2017, both referring to the line where i make_unique v2:

error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

error C2371: 'templategl::v2': redefinition; different basic types

EDIT: Yes, I should have provided a better example. And in creating one, I answered my own question. The revised code follows;

#include <memory>
#include <iostream>

struct vec3 {
    vec3() { x = y = z = 1.f; }
    vec3(float val) { x = y = z = val; }
    float x, y, z;
};

//smart pointers in a namespace...
namespace smptrns {
    std::unique_ptr<vec3>v0; //will be init in a namespace function
    std::unique_ptr<vec3>v1 = std::make_unique<vec3>(); //Works as expected
    std::unique_ptr<vec3>v2; //Declare a unique_ptr here, but i don't want to allocate any memory for it yet...
    //v2 = std::make_unique<vec3>(); //...NOW I want to allocate memory for v2 and prepare it to be used
    //^This is my problem, initializing v2 in namespace outside of a function.
    void initpntr() {
        v0 = std::make_unique<vec3>(); //Works
    }
}

int main() {
    smptrns::initpntr();
    smptrns::v2 = std::make_unique<vec3>(5.f); //Also works
    std::cout << smptrns::v0->x << "\t" << smptrns::v1->x << "\t" << smptrns::v2->x << "\n";
}

I was trying to initialize v2 outside of a function, fixed by either assigning to it from a function in the namespace, or within my main loop and accessing it directly with the :: operator. As I'm trying to reserve memory at runtime, this makes sense.


Solution

  • Solved, when my unique_ptr variable is declared elsewhere, std::make_unique needed to be called within a function, and not in a global or namespace scope.