Linkediting error when having a static unique_ptr [duplicate] - c++

This question already has answers here:
Undefined reference to static class member
(9 answers)
Undefined reference to a static member
(5 answers)
Closed last year.
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.

Related

Can i copy the libconfig::Setting from one libconfig::Config to another libconfig::Config?

I have a config ("/home/work/father.config") looks like:
father_config = {
child_config = "/home/work/child.config";
father_int = 1;
};
in /home/work/child.config:
child_config = {
child_int =2;
};
what i want is to get father_int from child_cfg.
please see the code:
#include <iostream>
#include <libconfig.h++>
using namespace std;
int main() {
libconfig::Config father_cfg;
father_cfg.readFile("./father.cfg");
const libconfig::Setting& father_setting = father_cfg.lookup("father_setting");
const std::string& child_path = father_setting.lookup("child_path");
libconfig::Config child_cfg;
child_cfg.readFile(child_path);
libconfig::Setting& child_setting = child_cfg.lookup("child_setting");
auto & s = child_cfg.getRoot().add("father_int", libconfig::Setting::TypeGroup);// father_setting.lookup("father_int");
s = father_setting; // !!!!!!! this doesn't work
int father_int = child_setting.lookup("father_int"); // the ulimate purpose is to make father int can be found in child_cfg
cout << father_int;
}
I know if the father_int is type int and the key-father_int wont change, i can use:
int father_int = father_setting.lookup("father_int");
child_cfg.GetRoot().add("father_int", libconfig::Setting::TypeInt) = father_int;
but i want this can be more flexible, which need to add libconfig::Setting::TypeGroup instead of libconfig::Setting::TypeInt,
Can you help on this?

Expected type got Element c++

Im trying to make a object / type that consists of an element of the periodic table. But when i try to use a vector of that object as a parameter, i get this error message expected a type, got ‘Element’
here is my code so far:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
Element(int AtomicNumm, string Symboll, string Namee, double Weightt,
int Neutronss, int Protonss, string ElectronConfigg) {
string Name = Namee;
int AtomicNum = AtomicNumm;
string Symbol = Symboll;
double Weight = Weightt;
int Neutrons = Neutronss;
int Protons = Protonss;
string ElectronConfig = ElectronConfigg;
}
string returnElement(vector<Element> vec, string input) { // error here
if (input.size() == 2) {
for (int i = 0; i < vec.length(); i++) {
}
}
return "";
}
int main(int argc, char*argv[]) {
vector<Element> PT;
string userinput (argv[1]);
return -1;
}
Also, im new to c++. If objects work completely differently here please let me know. (Coming from java)
That's because you haven't declared 'Element' in your program. Syntactically, it is close to definition of a constructor.
To make your program work, i guess you can do following modification to existing element:
class Element {
// your definition of element Here:
// also include default constructor without any implementation
Element() {}
};

C++ - List is not keeping its elements [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have 2 classes; TestUnit and TestShot.
TestUnit needs to hold a list of TestShots, however when I reference the list later on all the elements I've given it have disappeared!
TestUnit.h
#include <string>
#include <list>
#include "TestShot.h"
using namespace std;
class TestUnit
{
public:
TestUnit(string);
string getName(void);
void addShot(TestShot);
list<TestShot> getShots(void);
bool operator == (const TestUnit& tu) const { return name == tu.name; }
bool operator != (const TestUnit& tu) const { return !operator==(tu); }
private:
string name;
list<TestShot> shots;
};
TestUnit.cpp
#include "TestUnit.h"
TestUnit::TestUnit(string name)
{
this->name = name;
}
string TestUnit::getName(void)
{
return name;
}
void TestUnit::addShot(TestShot shot)
{
shots.push_front(shot);
}
list<TestShot> TestUnit::getShots(void)
{
return shots;
}
TestShot.h
#include <string>
using namespace std;
class TestShot
{
public:
TestShot(string);
string getName(void);
private:
string name;
};
TestShot.cpp
#include "TestShot.h"
TestShot::TestShot(string name)
{
this->name = name;
}
string TestShot::getName(void)
{
return name;
}
MAIN
#include <string>
#include "exports.h"
#include "TestUnit.h"
using namespace std;
// Global Variables
list<TestUnit> testUnits;
int main()
{
int nShots1 = 0;
int nShots2 = 0;
// Create Unit
TestUnit *testUnit = new TestUnit("Name");
testUnits.push_front(*testUnit);
// Create Shot and add to Unit with same 'name'
TestShot *testShot = new TestShot("Name");
for (TestUnit unit : testUnits)
{
if (unit.getName() == (*testShot).getName())
{
unit.addShot(*testShot);
nShots1 = unit.getShots().size();
}
}
// Display number of Shots for each Unit
for (TestUnit unit : testUnits)
{
nShots2 = unit.getShots().size();
std::cout << nShots1 << ", " << nShots2 << std::endl;
}
system("PAUSE");
};
Output:
1, 0
So the list realises that it's been populated straight after adding to it, but it's then empty when I need to use it.
I'm guessing this is a scope problem, but I can't seem to figure it out.
All help is much appreciated!
In each of your for loops, you're accessing the list elements by value, so you're effectively making a copy of what's in the list, modifying that, and then destroying it. Change your loops to look like this:
for (TestUnit &unit : testUnits)
{
if (unit.getName() == (*testShot).getName())
{
unit.addShot(*testShot);
nShots1 = unit.getShots().size();
}
}
Since you're using C++11 or later, you could also use auto instead of explicit typing (e.g., auto &unit: testUnits).

I want to print the most visited sites/urls in the browser

Below is the code that I have written in C++ and it is printing the wrong result for the 2nd and 3rd output line. I am not able to figure it out why it is happening.
Below is the code which I have written and it is a completely functional code on visual studio. This code expects the one input file named urlMgr.txt whose content should be URLs. Below is the sample URLs which I am using it.
web.whatsapp.com
web.whatsapp.com
cplusplus.com/reference/algorithm/find_if
stackoverflow.com/questions/760221/breaking-in-stdfor-each-loop
mail.google.com/mail/u/0/#inbox
http://stackoverflow.com/questions/18085331/recursive-lambda-functions-in-c14
mail.google.com/mail/u/0/#inbox
en.cppreference.com/w/cpp/language/lambda
https://www.google.co.in/?ion=1&espv=2#q=invariant%20meaning
mail.google.com/mail/u/0/#inbox
http://stackoverflow.com/questions/11699083/where-can-i-find-all-the-exception-guarantees-for-the-standard-containers-and-al
https://www.google.co.in/?ion=1&espv=2#q=array+of+references:quora&start=10
mail.google.com/mail/u/0/#inbox
web.whatsapp.com
quora.com/Whats-the-purpose-of-load-factor-in-hash-tables
https://www.quora.com/Whats-the-difference-between-the-rehash-and-reserve- methods-of-the-C++-unordered_map cplusplus.com/reference/unordered_map/unordered_map/load_factor
cplusplus.com/max_load_factor
cplusplus.com/max_load_factor
cplusplus.com/max_load_factor
cplusplus.com/max_load_factor
cplusplus.com/max_load_factor
cplusplus.com/max_load_factor
cplusplus.com/max_load_factor
cplusplus.com/max_load_factor
Code is also pasted below.
#include <iostream>
#include <string>
#include <unordered_set>
#include <algorithm>
#include <fstream>
#include <sstream>
#include <functional>
#include <unordered_map>
#include <queue>
using namespace std;
class urlInfo
{
public:
urlInfo(string &url):urlName(url),hitCount(1)
{
}
int getHitCount() const
{
return hitCount;
}
string getURL()
{
return urlName;
}
string getURL() const
{
return urlName;
}
void updateHitCount()
{
hitCount++;
}
void setHitCount(int count)
{
hitCount = count;
}
private:
string urlName;
int hitCount;
};
class urlInfoMaxHeap
{
public:
bool operator() (urlInfo *url1, urlInfo *url2) const
{
if(url2->getHitCount() > url1->getHitCount())
return true;
else
return false;
}
};
bool operator==(const urlInfo &ui1,const urlInfo& ui2)
{
//return (ui1.getURL().compare(ui2.getURL()) == 0) ? 1:0;
return (ui1.getURL() == ui2.getURL());
}
namespace std
{
template <> struct hash<urlInfo>
{
size_t operator()(urlInfo const & ui)
{
return hash<string>()(ui.getURL());
}
};
}
class urlMgr
{
public:
urlMgr(string &fileName)
{
ifstream rdStr;
string str;
rdStr.open(fileName.c_str(),ios::in);
if(rdStr.is_open())
{
int len;
rdStr.seekg(0,ios::end);
len = rdStr.tellg();
rdStr.seekg(0,ios::beg);
str.reserve(len+1);
char *buff = new char[len +1];
memset(buff,0,len+1);
rdStr.read(buff,len);
rdStr.close();
str.assign(buff);
delete [] buff;
}
stringstream ss(str);
string token;
while(getline(ss,token,'\n'))
{
//cout<<endl<<token;
addUrl(token);
}
}
void addUrl(string &url)
{
unordered_map<string,urlInfo*>::iterator itr;
itr = urls.find(url);
if(itr == urls.end())
{
urlInfo *u = new urlInfo(url);
urls[url] = u;
maxHeap.push_back(u);
}
else
{
itr->second->updateHitCount();
urlInfo* u = itr->second;
vector<urlInfo*>::iterator vItr;
vItr = find(maxHeap.begin(),maxHeap.end(),u);
if(vItr!=maxHeap.end())
{
maxHeap.erase(vItr);
maxHeap.push_back(u);
}
}
make_heap(maxHeap.begin(),maxHeap.end(),urlInfoMaxHeap());
}
void releaseResources()
{
for_each(urls.begin(),urls.end(),[](pair<string,urlInfo*> p){
urlInfo* u = p.second;
delete u;
});
}
void printHeap()
{
for_each(maxHeap.begin(),maxHeap.end(),[](urlInfo* u){
cout<<endl<<u->getHitCount()<<" "<<u->getURL();
});
}
private:
unordered_map<string,urlInfo*> urls;
vector<urlInfo*> maxHeap;
};
int main()
{
string fileName("urlMgr.txt");
urlMgr um(fileName);
um.printHeap();
um.releaseResources();
cout<<endl<<"Successfully inserted the data"<<endl;
}
The output i am getting is
8 cplusplus.com/max_load_factor
3 web.whatsapp.com
4 mail.google.com/mail/u/0/#inbox
1 en.cppreference.com/w/cpp/language/lambda
1 other url's and so on. //all other url's show count as 1.
What i expect is
8 cplusplus.com/max_load_factor
4 mail.google.com/mail/u/0/#inbox
3 web.whatsapp.com
1 en.cppreference.com/w/cpp/language/lambda
1 other url's and so on. //all other url's show count as 1.
Finally after some debugging i have found the problem.The problem is in the way you are interpreting how max_heap() works.
Consider this.
url1 occurs 8 times
url2 occurs 4 times
url3 occurs 3 times
After a call to max_heap() what you will get is
maxHeap[0]=8 8
maxHeap[1]=4 4 3
maxHeap[2]=3
Or you can also get
maxHeap[0]=8 8
maxHeap[1]=3 3 4
maxHeap[2]=4
Both of the above are maxHeaps but you are considering that only the first heap can occur and so in the below code you are just printing maxHeap content without realizing that you may be printing second heap.
void printHeap()
{
for_each(maxHeap.begin(),maxHeap.end(),[](urlInfo* u){
cout<<endl<<u->getHitCount()<<" "<<u->getURL();
});
}
To resolve this.One way is to after picking up maxHeap[0] .You delete first element and again call max_heap before picking up maxHeap[0] again.Or you can also have something like below.
while(maxHeap.size()>0){
cout<<(*maxHeap.begin())->getHitCount()<<" "<<(*maxHeap.begin())->getURL()<<endl;
std::pop_heap(maxHeap.begin(),maxHeap.end(),urlInfoMaxHeap());maxHeap.pop_back();}
In the above code pop_heap() will move the topmost element(which has the highest priority according to your implementation of compare function which you pass to make_heap()) to the end and heapify again. You can then delete the last element then.
Also i did not find the use of the below in your code
vector<urlInfo*>::iterator vItr;
vItr = find(maxHeap.begin(),maxHeap.end(),u);
if(vItr!=maxHeap.end())
{
maxHeap.erase(vItr);
maxHeap.push_back(u);
}

Problems returning vector stack reference

I am working on an application that builds a vector of structs for items in a given directory and returns a reference of the vector for it to be read, I receive the following errors when attempting to compile the example code below:
1. 'class std::vector<indexStruct, std::allocator<indexStruct> >' has no member named 'name'
2. no matching function for call to `std::vector<indexStruct, std::allocator<indexStruct> >::push_back(std::vector<indexStruct, std::allocator<indexStruct> >&)'
exampleApp.cpp
#include "exampleApp.h"
exampleApp::exampleApp()
{
this->makeCatalog();
}
char* findCWD()
{
char* buffer = new char[_MAX_PATH];
return getcwd(buffer, _MAX_PATH);
}
void exampleApp::makeCatalog()
{
char* cwd = this->findCWD();
vector<indexStruct> indexItems;
this->indexDir(cwd, indexItems);
}
void exampleApp:indexDir(char* dirPath, vector<indexStruct>& indexRef)
{
DIR *dirPointer = NULL;
struct dirent *dirItem = NULL;
vector<indexStruct> indexItems;
vector<indexStruct> indexItem;
try
{
if ((dirPointer = opendir(dirPath)) == NULL) throw 1;
while (dirItem = readdir(dirPointer))
{
if (dirItem == NULL) throw 2;
if (dirItem->d_name[0] != '.')
{
indexItem.name = dirItem->d_name;
indexItem.path = dirPath;
indexItems.push_back(indexItem);
indexItem.clear();
}
}
indexRef.swap(indexItems);
closedir(dirPointer);
}
catch(int errorNo)
{
//cout << "Caught Error #" << errorNo;
}
}
exampleApp.h
#ifndef EXAMPLEAPP_H
#define EXAMPLEAPP_H
#include <iostream.h>
#include <dirent.h>
#include <stdlib.h>
#include <vector.h>
using namespace std;
struct indexStruct
{
char* name;
char* path;
};
class exampleApp
{
public:
exampleApp();
private:
char* findCWD();
void makeCatalog();
void indexDir(char* dirPath, vector<indexStruct>& indexRef);
};
#endif
What am I doing wrong here, and is there a better way going about this?
You've made 'indexItem' a vector, you probably just want it to be the type you want to put in 'indexItems'. Also, I'd create the new struct in your loop:
while (dirItem = readdir(dirPointer))
{
if (dirItem == NULL) throw 2;
if (dirItem->d_name[0] != '.')
{
indexStruct indexItem;
indexItem.name = dirItem->d_name;
indexItem.path = dirPath;
indexItems.push_back(indexItem);
}
}
You are defining a vector called indexItem:
vector<indexStruct> indexItem;
This is just an array. So the following lines must be changed to reference a specific element of the vector:
indexItem.name = dirItem->d_name;// should be indexItem[..].name or indexItem.at(..).name
indexItem.path = dirPath; // same as above!