1

Because I want my unique_ptr to be the same in all my objects, I decided to make it a static field.

After that an error has appeared:

https://pastebin.com/PPe6z0Ub

I don't really know how to fix it, I've tried searching for it online but I couldn't find anything really useful.

Code: DBFeed.h

#pragma once
#include <vector>
#include <string>
#include <memory>

class DBFeed
{
public:
    void CalculatePosts();
    std::vector<std::string> GetPost();
    void ClearFeed();
private:
    static std::unique_ptr<std::vector<std::vector<std::string>>> m_postari;
    static int m_index;
};

DBFeed.cpp

#include "DBFeed.h"
#include "DBLink.h"

int DBFeed::m_index = 0;

void DBFeed::CalculatePosts()
{
    DBFeed::m_postari = std::make_unique<std::vector<std::vector<std::string>>>();
    pqxx::work worker(*DBLink::GetInstance());
    try
    {
        worker.conn().prepare("CountPostsFeed", "SELECT COUNT(id) FROM posts");
        worker.conn().prepare("ReadAllPostsFeed",
            "SELECT message FROM followers RIGHT JOIN posts ON followers.followed = posts.user_id WHERE followers.follower = 51 LIMIT 5 OFFSET" + std::to_string(m_index+=5)
        );
        pqxx::row countPostsResult = worker.exec_prepared1("CountPostsFeed");
        std::string number = countPostsResult.at("count").c_str();
        pqxx::result readAllPostsResult = worker.exec_prepared_n(std::stoi(number), "ReadAllPostsFeed");
        for (const auto& currentPost : readAllPostsResult)
        {
            std::string postID = currentPost.at("id").c_str();
            std::string message = currentPost.at("message").c_str();
            std::string dateCreated = currentPost.at("date_created").c_str();
            DBFeed::m_postari->push_back(std::vector<std::string>{postID, message, dateCreated});
        }
        worker.commit();
    }
    catch (const pqxx::unexpected_rows&)
    {
        throw std::runtime_error("Reading all of an users posts for feed failed");
    }
}

std::vector<std::string> DBFeed::GetPost()
{
    if (m_postari->empty())
    {
        CalculatePosts();
    }
    std::vector<std::string> deReturnat = m_postari->at(0);
    m_postari->erase(m_postari->begin());
    return deReturnat;
}

void DBFeed::ClearFeed()
{
    m_index = 0;
    m_postari.reset();
}

Why is this error happening and how can I fix it?

//Edit:

Fixed it by adding this by changing DBFeed.cpp's first lines as follows:

#include "DBFeed.h"
#include "DBLink.h"

int DBFeed::m_index = 0;
std::unique_ptr<std::vector<std::vector<std::string>>> 
DBFeed::m_postari = std::make_unique<std::vector<std::vector<std::string>>>();

void DBFeed::CalculatePosts()
{
    pqxx::work worker(*DBLink::GetInstance());
....

But I'd still like to get an explanation on why it was happening and why is it fixed now.

Octavian Niculescu
  • 1,177
  • 1
  • 3
  • 24
  • 1
    In your header file you may just write `inline static std::unique_ptr.....` instead of current `static std::unique_ptr....` (i.e. just add word `inline`). But this inline ability appeared only in C++14 or C++17 standard. To explain why error was happening in your case is because you just Declared static variable in header. But all static class variables in C++11 should be Defined in .cpp file, that what you did in your .cpp. Even if variable is default-initialized (just `var;` instead of `var = something();`) still you need to Define it in .cpp. – Arty Jan 12 '22 at 01:27
  • 1
    Extending my previous comment - if you add word `inline` then your error is fixed and you don't need anything in .cpp regarding this variable. But be aware that in this case your variable will have null pointer inside, you still have to write some value into it at some point in time. – Arty Jan 12 '22 at 01:34
  • 2
    "But I'd still like to get an explanation on why it was happening and why is it fixed now.": It is happening for the exact same reason that you needed to add `int DBFeed::m_index = 0;`: static class members (which are not inline) must be defined outside the body of the class. I am not sure what you think is different for `m_postari`. – user17732522 Jan 12 '22 at 01:40
  • 1
    Templates tend to contribute to, shall we say, verbose error messages. To get an error message down to something reasonable to paste directly in your question, you should consider simplifying the type used in the *example* code *for this question*. Instead of `std::unique_ptr>>`, try something using only one template, as in `std::unique_ptr` or even better something using no templates, as in `int`. (Note that I did not simplify to `std::string` since that is also a template, even though you don't have to specify template arguments.) – JaMiT Jan 12 '22 at 01:53

0 Answers0