C++ includes, class namespacing, and class instantiation - c++

I've been writing some code to try and model some kind of taxi service, but I've run into a bit of an issue.
I have a class RunServer, which looks at the state of commands given by the user (src::control::Global::stat_commandPath) and asks for additional input based on those commands before doing something with that input.
The problem is that I'm getting an "error: expected type-specifier" (GCC-7.3.0, C++11) and it looks like it might have something to do with how I've namespaced the classes. If namespace declarations are removed from src/Vehicle/Car.h, then this problem stops happening.
This is should be all the relevant code for this issue. Sorry there's so much of it, I've truncated everything that doesn't look like it has an impact. The problem is with src/control/RunServer.h lines 66, 70, and 74. src/vehicle/Pickup.h and src/vehicle/Van.h have the same structure as src/vehicle/Car.h.
src/control/Global.h
#ifndef INCLUDED_src_control_Global_h
#define INCLUDED_src_control_Global_h
#include <string>
#include "../vehicle/Vehicle.h"
namespace src {
namespace control {
class Global final
{
virtual void instantiable() = 0;
private:
static size_t
stat_vehicleArrayLength;
static src::Vehicle
** stat_vehicleArray;
public:
static std::string
stat_commandPath,
stat_stdcoutEnd;
public:
static bool
// Deletes the pointer argument if adding fails.
add_vehicle(
src::Vehicle *
),
exists_vehicle(
std::string
),
remove_vehicle(
std::string
);
static size_t
get_vehicleAmount(),
position_vehicle(
std::string
);
static src::Vehicle
** get_vehicles();
};
}}
#endif
src/control/RunServer.cpp
#include <iostream>
#include <stdlib.h> // exit()
#include <string>
#include <regex>
#include "../../lib/StringTools.h"
#include "../vehicle/Car.h"
#include "../vehicle/Pickup.h"
#include "../vehicle/Van.h"
#include "../vehicle/VehicleType.h"
#include "../person/Driver.h"
#include "../person/Passenger.h"
#include "Global.h"
#include "RunServer.h"
inline bool
src::control::RunServer::navigation(
std::string input)
{
if (input == "return")
{
src::control::Global::stat_commandPath.pop_back();
return true;
}
if (input == "exit")
{
exit(0);
return true;
}
return false;
}
void
src::control::RunServer::run()
{
std::string input;
// "0" ~ Create...
// "00" ~ Create > Vehicle...
// "000" ~ Create > Vehicle > Car
// "001" ~ Create > Vehicle > Pickup
// "002" ~ Create > Vehicle > Van
// "01" ~ Create > Person...
// "010" ~ Create > Person > Driver
// "011" ~ Create > Person > Passenger
// "1" ~ Destroy...
// "10" ~ Destroy > Vehicle
// "11" ~ Destroy > Passenger
// "2" ~ Print
if (src::control::Global::stat_commandPath == "000" || src::control::Global::stat_commandPath == "001" || src::control::Global::stat_commandPath == "002")
{
// Create > Vehicle > (Car|Pickup|Van).
std::cout << "\n";
std::cout << "<vehicle identification (char array)>" << src::control::Global::stat_stdcoutEnd;
getline(std::cin, input);
if (src::control::RunServer::navigation(input))
{
return;
}
if (std::regex_match(input, std::regex("\\w+")))
{
if (src::control::Global::stat_commandPath.back() == '0' && !src::control::Global::add_vehicle(new src::vehicle::Car(input)))
{
std::cout << "\nA vehicle with this identifier already exists!\n";
}
else if (src::control::Global::stat_commandPath.back() == '1' && !src::control::Global::add_vehicle(new src::vehicle::Pickup(input)))
{
std::cout << "\nA vehicle with this identifier already exists!\n";
}
else if (src::control::Global::stat_commandPath.back() == '2' && !src::control::Global::add_vehicle(new src::vehicle::Van(input)))
{
std::cout << "\nA vehicle with this identifier already exists!\n";
}
else
{
std::cout << "\nAn error occured!\n";
}
}
}
}
src/vehicle/Car.h
#ifndef INCLUDED_src_vehicle_Car_h
#define INCLUDED_src_vehicle_Car_h
#include <string>
#include "Vehicle.h"
namespace src {
namespace vehicle {
class Car final : public src::Vehicle
{
void instantiable() override {};
public:
Car();
Car(
std::string
);
int
canAddPassenger(
src::person::Passenger *
) override;
};
}}
#endif

This is completely wrong:
static bool
// Deletes the pointer argument if adding fails.
add_vehicle(
src::Vehicle *
),
exists_vehicle(
std::string
),
remove_vehicle(
std::string
);
What are you trying to accomplish here? Isn't this supposed to be 3 independent prototypes?
static bool
// Deletes the pointer argument if adding fails.
add_vehicle(
src::Vehicle *
);
static bool exists_vehicle(
std::string
);
static bool remove_vehicle(
std::string
);

Issue appears to be related to case. It seems like namespace lookup is not case sensitive while namespace declaration is. Changing the namespace of src::vehicle::Car to src::avehicle::Car fixed the issue.

Related

How can I access and modify the attributes of a class stored in a vector if I delete the "original" object?

I'm making an application that allows to quote clothes in a store.
In my Store class, I have defined a vector of class Clothes, where I must store the different types of clothing to sell (derived clothing classes such as Shirt and Pants).
My problem arises in that, it does not allow me to access the objects stored in the vector if I have deleted the "original" object. From what I understood, std::vector performed a copy constructor and had its own space to store data, so it is not clear to me why I am not being able to access and modify the attributes of the objects that are already inside the vector. Depending on the different solutions that I tried, the compiler showed me different read or write access errors.
PS: If I don't delete the original object (after having entered the vector), the code works fine for me, and allows me to remove it from the vector and add another object, which I CAN DELETE after entering it into the vector.
Store.h
#pragma once
#ifndef STORE_H
#define STORE_H
#include <string>
#include <vector>
class Clothes;
class Shirt;
class Pants;
class Store
{
private:
std::string storeName;
std::string address;
std::vector<Clothes*> clothesList;
Shirt* _shirt;
Pants* _pants;
public:
Store();
~Store();
void setClothesPreferences(int clothesType, int alternative1, int alternative2, int quality);
};
#endif // !STORE_H
Store.cpp
#include "Store.h"
#include "Clothes.h"
#include "Shirt.h"
#include "Pants.h"
#include <iostream>
Store::Store()
{
std::cout << "Please, introduce your store name: ";
std::getline(std::cin, storeName);
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Store address: ";
std::getline(std::cin, address);
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
_shirt = new Shirt();
_pants = new Pants();
clothesList.push_back(_shirt);
clothesList.push_back(_pants);
// If I use delete _shirt here then I would get an error in setClothesPreferences()
}
Store::~Store()
{
std::cout << "Store closed" << std::endl;
}
void Store::setClothesPreferences(int clothesType, int alternative1, int alternative2, int quality)
{
if (clothesType == 1)
{
Shirt* _shirt2 = dynamic_cast<Shirt*>(clothesList.front()); // Type-casting from Clothes (base class) to Shirt again (derived class)
clothesList.erase(clothesList.begin());
// SHIRT SPECIFICATIONS FOR FURTHER QUOTE
if (alternative1 == 1)
_shirt2->shortSleeve = true;
else
_shirt2->shortSleeve = false; // longSleeve
if (alternative2 == 1)
_shirt2->mandarinCollar = true;
else
_shirt2->mandarinCollar = false; // regularCollar
if (quality == 1)
_shirt2->quality; // Standard
else
_shirt2->quality; // Premium
clothesList.insert(clothesList.begin(), _shirt2);
}
}
Clothes.h
#pragma once
#ifndef CLOTHES_H
#define CLOTHES_H
#include <string>
class Clothes
{
public:
std::string derivedName;
std::string quality[2];
double unitPrice;
int stockAmount;
Clothes();
virtual ~Clothes();
};
#endif // !CLOTHES_H
Clothes.cpp
#include "Clothes.h"
Clothes::Clothes()
{
derivedName = "Base default";
quality[0] = "Standard";
quality[1] = "Premium";
unitPrice = NULL;
}
Clothes::~Clothes()
{
}
Shirt.h
#pragma once
#ifndef SHIRT_H
#define SHIRT_H
#include "Clothes.h"
class Shirt : public Clothes
{
public:
bool shortSleeve;
bool mandarinCollar;
Shirt();
~Shirt() override;
};
#endif // !SHIRT_H
Shirt.cpp
#include "Shirt.h"
Shirt::Shirt()
{
derivedName = "Shirt";
stockAmount = 2000;
}
Shirt::~Shirt()
{
}
My idea is actually to create a local object of class Shirt, insert it into the vector, and when the Clothes function or constructor is finished, it would be deleted, but I would still have access and modify its data from what is stored in the vector.

Find If-Conditions using Clang

I'm trying to find the if-conditions in a C-code using Clang.
What I've learned till now is to find the declarations using HandleTopLevelDecl().
What I'm trying to do now is to find a function that is similar to HandleTopLevelDecl() but handles the If-Conditions.
My question is, am I on the right path? is there a function that can do this?
And if not, what do you advice me to do?
Thanks.
With the help of this awesome course: http://swtv.kaist.ac.kr/courses/cs453-fall13
Specially this tutorial: http://swtv.kaist.ac.kr/courses/cs453-fall13/Clang%20tutorial%20v4.pdf
I have solved the problem.
I needed to create a RecursiveASTVisitor and handle the If-Statements while visiting the Statements.
class MyASTVisitor : public RecursiveASTVisitor<MyASTVisitor>
{
public:
bool VisitStmt(Stmt *s) {
// Search for If-Statements
if(isa<IfStmt>(s))
{
cerr << "Found IF" << endl;
}
return true;
}
bool VisitFunctionDecl(FunctionDecl *f) {
// Print function name
cerr << f->getNameAsString().c_str() << endl;
return true;
}
};
And here are the complete code:
#include <cstdio>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <utility>
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/ParseAST.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "clang/Rewrite/Frontend/Rewriters.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
using namespace std;
// CompilerInstance
CompilerInstance TheCompInst;
class MyASTVisitor : public RecursiveASTVisitor<MyASTVisitor>
{
public:
bool VisitStmt(Stmt *s) {
// Search for If-Statements
if(isa<IfStmt>(s))
{
SourceManager &srcmgr = TheCompInst.getSourceManager();
SourceLocation startLocation = s->getLocStart();
unsigned int start_lineNum = srcmgr.getExpansionLineNumber(startLocation);
cerr << "Found IF # Line: " << start_lineNum << endl;
}
return true;
}
bool VisitFunctionDecl(FunctionDecl *f) {
// Print function name
cerr << f->getNameAsString().c_str() << endl;
return true;
}
};
class MyASTConsumer : public ASTConsumer
{
public:
MyASTConsumer()
: Visitor() //initialize MyASTVisitor
{}
virtual bool HandleTopLevelDecl(DeclGroupRef DR) {
for (DeclGroupRef::iterator b = DR.begin(), e = DR.end(); b != e; ++b) {
// Travel each function declaration using MyASTVisitor
Visitor.TraverseDecl(*b);
}
return true;
}
private:
MyASTVisitor Visitor;
};
int main(int argc, char *argv[])
{
if (argc != 2) {
llvm::errs() << "Usage: kcov-branch-identify <filename>\n";
return 1;
}
// Diagnostics manage problems and issues in compile
TheCompInst.createDiagnostics(NULL, false);
// Set target platform options
// Initialize target info with the default triple for our platform.
TargetOptions *TO = new TargetOptions();
TO->Triple = llvm::sys::getDefaultTargetTriple();
TargetInfo *TI = TargetInfo::CreateTargetInfo(TheCompInst.getDiagnostics(), TO);
TheCompInst.setTarget(TI);
// FileManager supports for file system lookup, file system caching, and directory search management.
TheCompInst.createFileManager();
FileManager &FileMgr = TheCompInst.getFileManager();
// SourceManager handles loading and caching of source files into memory.
TheCompInst.createSourceManager(FileMgr);
SourceManager &SourceMgr = TheCompInst.getSourceManager();
// Prreprocessor runs within a single source file
TheCompInst.createPreprocessor();
// ASTContext holds long-lived AST nodes (such as types and decls) .
TheCompInst.createASTContext();
// A Rewriter helps us manage the code rewriting task.
Rewriter TheRewriter;
TheRewriter.setSourceMgr(SourceMgr, TheCompInst.getLangOpts());
// Set the main file handled by the source manager to the input file.
const FileEntry *FileIn = FileMgr.getFile(argv[1]);
SourceMgr.createMainFileID(FileIn);
// Inform Diagnostics that processing of a source file is beginning.
TheCompInst.getDiagnosticClient().BeginSourceFile(TheCompInst.getLangOpts(),&TheCompInst.getPreprocessor());
// Create an AST consumer instance which is going to get called by ParseAST.
MyASTConsumer TheConsumer;
// Parse the file to AST, registering our consumer as the AST consumer.
ParseAST(TheCompInst.getPreprocessor(), &TheConsumer, TheCompInst.getASTContext());
return 0;
}
There are specific functions in clang for all kinds of Stmts and Decls. For this particular case, it is going to be VisitIfStmt. Check IfStmt being included in RecusiveASTVisitor.h.
RecursiveASTVisitor.h -
#define STMT(CLASS, PARENT) \
bool WalkUpFrom##CLASS(CLASS *S) { \
TRY_TO(WalkUpFrom##PARENT(S)); \
TRY_TO(Visit##CLASS(S)); \
return true; \
} \
bool Visit##CLASS(CLASS *S) { return true; }
#include "clang/AST/StmtNodes.inc"
clang/AST/StmtNodes.inc -
#ifndef IFSTMT
# define IFSTMT(Type, Base) STMT(Type, Base)
#endif
IFSTMT(IfStmt, Stmt)
#undef IFSTMT
These, together create the function VisitIfStmt(IfStmt*) in the class.

Error assigning object to pointer c++

Me and my friend are making a text based game in c++ for fun, and to learn a little more. I have been trying to use pointers to classes, but am having no luck, and some errors are occurring which make absolutely no sense to me at all, and am hoping someone can help me.
Code:
//Map.h
#include "Player.h"
class Map
{
//Virtual functions
};
class StartMap : public Map
{
//Code
}Start;
class JungleMap : public Map
{
//Code
}Jungle;
class RiverMap : public Map
{
//Code
}River;
//Player.h
#ifndef MAP_H
#define MAP_H
#endif
class Player
{
private:
Map *PlayerMap;
//Other variables
public:
void Initialize()
{
//Initialize variables
PlayerMap = &Start; //This is where the error occurs, says there's a
//<error-type>*Player::PlayerMap. Tried putting
//this->PlayerMap = &Start, didn't help
//There's no error when I make the pointer
}
//Bunch of other functions
}Player;
Okay, here's my code since I decided to add .cpp files:
//Command.h
class Command
{
private:
string GameCommand;
void Trim();
public:
Command (string command) {GameCommand = command;}
Command () {}
void operator = (string command) {GameCommand = command;}
void ReadCommand();
string Print();
}
//Command.cpp
#include <iostream>
#include <string>
#include "Command.h"
#include "Parameter.h"
using namespace std;
void Command::Trim()
{
int LeadingPos = 0, MidCount = 0, TrailingPos = GameCommand.length()-1, Size = 0;
string TempCommand = "";
while (GameCommand[LeadingPos] == ' '){LeadingPos += 1;}
while (GameCommand[TrailingPos] == ' '){TrailingPos -= 1;}
Size = ((TrailingPos+1)-LeadingPos);
for (int loops = 0; loops < Size; loops++)
{
if (MidCount > 0 && GameCommand[LeadingPos] == ' ')
{
LeadingPos += 1;
}
else
{
if (GameCommand[LeadingPos] == ' ')
{
MidCount += 1;
}
TempCommand += GameCommand[LeadingPos];
LeadingPos += 1;
}
}
GameCommand = TempCommand;
}
void Command::ReadCommand()
{
Trim();
string Parameter;
if (GameCommand.substr(0,3) == "go ")
{
Parameter = GameCommand.substr(3,string::npos);
CommandParameter.Go(Parameter);
}
else if (GameCommand.substr(0,4) == "dig ")
{
Parameter = GameCommand.substr(4,string::npos);
CommandParameter.Dig(Parameter);
}
else if (GameCommand.substr(0,4) == "eat ")
{
Parameter = GameCommand.substr(4,string::npos);
CommandParameter.Eat(Parameter);
}
else if (GameCommand.substr(0,4) == "exit" || GameCommand.substr(0,4) == "quit")
{
exit(0);
}
else if (GameCommand.substr(0,4) == "use ")
{
Parameter = GameCommand.substr(4,string::npos);
CommandParameter.Use(Parameter);
}
else if (GameCommand.substr(0,5) == "drop ")
{
Parameter = GameCommand.substr(5,string::npos);
CommandParameter.Drop(Parameter);
}
else if (GameCommand.substr(0,5) == "grab " || GameCommand.substr(0,5) == "take ")
{
Parameter = GameCommand.substr(5,string::npos);
CommandParameter.Pickup(Parameter);
}
else if (GameCommand.substr(0,5) == "help ")
{
Parameter = GameCommand.substr(5,string::npos);
CommandParameter.Help(Parameter);
}
else if (GameCommand.substr(0,5) == "look ")
{
Parameter = GameCommand.substr(5,string::npos);
CommandParameter.Look(Parameter);
}
else if (GameCommand.substr(0,5) == "sleep")
{
CommandParameter.Sleep();
}
else if (GameCommand.substr(0,6) == "check ")
{
Parameter = GameCommand.substr(6,string::npos);
CommandParameter.Check(Parameter);
}
else if (GameCommand.substr(0,6) == "climb ")
{
Parameter = GameCommand.substr(6,string::npos);
CommandParameter.Climb(Parameter);
}
else if (GameCommand.substr(0,6) == "throw ")
{
Parameter = GameCommand.substr(6,string::npos);
CommandParameter.Throw(Parameter);
}
else if (GameCommand.substr(0,7) == "attack ")
{
Parameter = GameCommand.substr(7,string::npos);
CommandParameter.Attack(Parameter);
}
else if (GameCommand.substr(0,7) == "search ")
{
Parameter = GameCommand.substr(7,string::npos);
CommandParameter.Search(Parameter);
}
else
{
cout << "Not a valid command.\n";
}
}
string Print()
{
return GameCommand;
}
The string GameCommand is what's not working.
class StartMap : public Map;
is syntactically incorrect. You need
class StartMap : public Map
{
// Details of class
} Start;
You need to make similar changes to JungleMap and RiverMap.
First thing I noticed was the semi-colon after each inheritance declaration..
class XXXXX : public Map; <-- that semi-colon shouldn't be there..
In the initialize function, I'm fairly certain you mean PlayerMap = new StartMap();
You'll need a destructor to delete it and a copy, move constructor as well as an assignment operator in order to assign, move or copy the class.
You can follow this to make the class conform to RAII: What is the copy-and-swap idiom?
There are lots of problems with your code layout.
This doesn't do anything:
//Player.h
#ifndef MAP_H
#define MAP_H
#endif
I guess you are trying to do an include guard. The proper layout is:
#ifndef PLAYER_H
#define PLAYER_H
// all your code for the header file goes here
class Player
{
// ....
};
#endif // no more code after this line
The next issue is that Player.h should include Map.h, not the other way around. Imagine you are the compiler. You are processing Player.h. You get down as far as Map *PlayerMap; . But you don't know what Map is because you haven't seen Map.h yet. So you have to give an error and stop compiling.
The map definitions in Map.h should look like:
class StartMap : public Map
{
//Code
};
The Start; you had on the end is poor style. It would cause undefined behaviour if two different .cpp files included Map.h because there would be two different global variables with the same name.
Moving onto the void Map::Initialize() function. You're supposed to use the constructor for initialization. Either way, my suggestion is that you don't implement this in Player.h. Instead, just have void Initialize();, and then in Map.cpp you could have:
// the global variables
StartMap start_map;
JungleMap jungle_map;
void Map::Initialize()
{
player_map = &start_map;
}
It's a good idea to use a different naming convention for classes than for variables. So that when someone sees StartMap for example, they know immediately whether it is a class name or a variable name.

C++11 Cereal: load_and_allocate not loading correctly

I am using cereal, a C++11 serialization library. I am uncertain if this is a bug with the library or an issue with how I am using it and I would like some assistance.
Given the following minimal repro which is representative (but not reliant) on my own code I am getting an exception thrown from JSONInputArchive::search as invocated by the line next to my comment in the code sample below (//breaks here.)
I'm currently on commit 436a0a275cda007f137876f37b4fc8783e615352 in this github repro (at the time of writing, the tip of their develop branch.)
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include "cereal/cereal.hpp"
#include "cereal/types/map.hpp"
#include "cereal/types/vector.hpp"
#include "cereal/types/memory.hpp"
#include "cereal/types/string.hpp"
#include "cereal/types/base_class.hpp"
#include "cereal/archives/json.hpp"
#include <cereal/types/polymorphic.hpp>
class BaseClass : public std::enable_shared_from_this<BaseClass> {
public:
virtual ~BaseClass(){}
template <class Archive>
void serialize(Archive & archive){
archive(CEREAL_NVP(name), CEREAL_NVP(baseMember));
}
protected:
BaseClass(const std::string &a_name):
name(a_name){
}
std::string name;
int baseMember; //let this have random junk so we can see if it saves right.
};
class DerivedClass : public BaseClass {
friend cereal::access;
public:
static std::shared_ptr<DerivedClass> make(const std::string &a_name, int a_derivedMember){
return std::shared_ptr<DerivedClass>(new DerivedClass(a_name, a_derivedMember));
}
template <class Archive>
void serialize(Archive & archive){
archive(CEREAL_NVP(derivedMember), cereal::make_nvp("base", cereal::base_class<BaseClass>(this)));
}
private:
DerivedClass(const std::string &a_name, int a_derivedMember):
BaseClass(a_name),
derivedMember(a_derivedMember){
}
template <class Archive>
static DerivedClass * load_and_allocate(Archive &archive){
int derivedMember;
archive(CEREAL_NVP(derivedMember)); //breaks here.
DerivedClass* object = new DerivedClass("", derivedMember);
archive(cereal::make_nvp("base", cereal::base_class<BaseClass>(object)));
return object;
}
int derivedMember;
};
CEREAL_REGISTER_TYPE(DerivedClass);
void saveTest(){
std::stringstream stream;
{
cereal::JSONOutputArchive archive(stream);
auto testSave = DerivedClass::make("TestName", 4);
archive(cereal::make_nvp("test", testSave));
}
std::cout << stream.str() << std::endl;
std::shared_ptr<DerivedClass> loaded;
{
cereal::JSONInputArchive archive(stream);
archive(cereal::make_nvp("test", loaded));
}
std::stringstream stream2;
{
cereal::JSONOutputArchive archive(stream2);
archive(cereal::make_nvp("test", loaded));
}
std::cout << stream2.str() << std::endl;
std::cout << "TA-DA!" << std::endl;
}
int main(){
saveTest();
}
The sample output I get from the above (before the exception) is:
{
"test": {
"id": 1073741824,
"ptr_wrapper": {
"id": 2147483649,
"data": {
"derivedMember": 4,
"base": {
"name": "TestName",
"baseMember": -1163005939
}
}
}
}
}
I've modified the throwing method (in cereal/archive/json.hpp) to print what it is searching for and each of the values it is looking through in an effort to debug the problem. Here is my modified version:
//! Adjust our position such that we are at the node with the given name
/*! #throws Exception if no such named node exists */
inline void search( const char * searchName )//, GenericValue const & parent )
{
size_t index = 0;
std::cout << "_____" << std::endl;
for( auto it = itsMemberItBegin; it != itsMemberItEnd; ++it, ++index )
if( std::strcmp( searchName, it->name.GetString() ) == 0 )
{
itsIndex = index;
return;
} else{
//I added this part here
std::cout << "!" << searchName << " == " << it->name.GetString() << std::endl;
}
throw Exception("JSON Parsing failed - provided NVP not found");
}
Output for the above method before it excepts:
!derivedMember == id
!derivedMember == data
The output I get from this seems to indicate that search is looking through the members of "test.ptr_wrapper" instead of "test.ptr_wrapper.data".
My question is this: am I doing something wrong? Or is there an issue with cereal?
https://github.com/USCiLab/cereal/issues/42
It seems like this is indeed a bug with Cereal. My temporary work-around is as follows:
For now, to work around the issue I added a line 144 in memory.hpp (as
it appears on line 168 in the case of no load_and_allocate which means
that there is a default constructor.)
ar( *ptr );
I will simply avoid using the load_and_allocate archive
directly and will use my serialization functions. In my
load_and_allocate method I will construct an object with "default"
like information.
When this is fixed I should be able to correctly load in the parameters required to construct the object properly.
*edit: this has been fixed on the develop branch.

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!