define list in header vertice on c++ - c++

I have problem with define syntax of List this error that I getting, I tried creating a list of Vertice and I have problem with the syntax, I tried using namespace STD also in a header but still getting an error:
Severity Code Description Project File Line Suppression State
Error (active) E0415 no suitable constructor exists to convert from "std::list> *" to "std::list>" graf C:\Users\danie\OneDrive\Desktop\graf\graf\Vertice.cpp 39
Vertice.h
#pragma once
#include <list>
#include <iostream>
class Vertice {
std::list<Vertice> getList();
void setList(Vertice v);
private:
std::list<Vertice> *N;
};
Vertice.cpp
#pragma once
#include <list>
#include <iostream>
#include "Vertice.h"
using namespace std;
Vertice::Vertice(int b, int f) {
N = new list < Vertice > ();
color = 0;
}
list < Vertice > Vertice::getList() {
return N;
}
void Vertice::setList(Vertice v) {
this - > N - > push_front(v);
}
Vertice::~Vertice() {
N - > clear();
}

The reason why you are getting comments and not answers is because you
a) Did not post the error message (as mentioned in a comment)
b) Your code contains many errors and some anti-patterns.
When using namespaces in C++ the convention is to use the full namespace in header
std::list<Vertice> *N; // member declaration
and a "using" declaration in the module.
using namespace std;
...
list<Vertice> Vertice::getList() const // return by value, mark as const
{
return N; // you don't need this->N in C++
}
However, many people prefer to simply type the full namespace always, so if you find this easier to understand, try using that.
What are you trying to achieve with this code? The reason I ask is because dynamically allocating a "std::list" is a bit weird. A "std::list" is designed to manage memory for you, which makes this code read a bit like "allocate a pointer to hold the address of the memory I'm about to allocate". I strongly suspect you are trying to make a recursive structure (a tree). Surprisingly C++ does not require you to use pointers to do this (C does). Maybe this pattern will help?
class NTree
{
private:
std::list<NTree> children;
};
I would suggest you get your code working like that first. If need to optimize, you will more control of the memory, then something like this will help.
class NTree
{
private:
std::vector<std::unique_ptr<NTree>> children;
};
This will allow you to, for example, move a child from one node (NTree) to another (NTree - or other), in a safe way. This avoids any copying overhead. This is a minor saving unless either your trees get very big or they contain objects which are very big. Even expert C++ programmers will try and get their code working before trying an optimization like this. There is no way to predict if it will required or not, so as always benchmark before and after.

Related

Adressing variables by variable names [duplicate]

This question already has answers here:
Iterate through Struct and Class Members [duplicate]
(6 answers)
Closed 2 years ago.
I am currently writing a ROS 2 node to pass values from a PLC through ROS to a visualization:
PLC System --> ROS --> Visualization
Since ROS should only pass on the data, I want to be able to configure the interface here with as little effort as possible. The idea, which can be implemented best with ROS, would be a config-file(.msg file), in which the designation of the variables and their type is entered. Everything else is then derived from this.
The problem I inevitably run into with this: In ROS data are passed on over so-called messages. These messages are defined via structs and are automatically generated from my config-file. To assign values to the variables from the struct, I don't want to address every single one hardcoded in the program, but rather iterate through the struct using the known names.
TLNR: Can variables be addressed with variable variable names?
I know that the whole thing sounds a bit confusing. I hope the following example will clarify what I mean:
#include <vector>
#include <string>
struct MsgFile
{
int someVariable;
int someOtherVariable;
};
using namespace std;
class Example
{
public:
vector<string> variableNames{"someVariable", "someOtherVariable"};
MsgFile message;
void WriteVariables()
{
for (auto const &varName : variableNames)
{
message."varName" = 0; //<-- pseudo code of what I'm thinking of
}
}
};
Regards
Tillman
You cannot use variable names like that. There are no variable names at runtime. If you want a mapping between names (strings) and variables, you need to add that yourself.
If your "variables" are of same type, eg int, you can use a map:
#include <vector>
#include <string>
#include <unordered_map>
using MsgFile = std::unordered_map<std::string,int>;
struct Example {
std::vector<std::string> variableNames{"someVariable", "someOtherVariable"};
MsgFile message;
void WriteVariables() {
for (auto const &varName : variableNames) {
message[varName] = 0; // add an entry { varName, 0 } to the map
// (or updates then entry for key==varName when it already existed)
}
}
};
If you only need the string representation to access it (but not for printing etc) you can consider to use an enum as key instead. At least I'd define some constants like const std::string some_variable{"some_variable"}, to avoid typos going unnoticed (perhaps the variableNames is supposed to be const (and static?)).
As far as I know there is no standard way to do this, I would choose another way to store the data ( I mean not in struct ), but if you are adamant here is an answered question:
Get list of C structure members

Using alias from header file in corresponding source file

I just started learning more of c++ and am writing a small rendering engine as an example case study. As i started to implement more code I got annoyed by typing types like
std::vector<std::vector<int>>
over and over again. As most of you know already, this get's infinitely worse if you are looping over said vector
for (std::vector<std::vector<Tile>>::const_iterator layerRow = ...) {}
Since this is not just annoying but also very error prone, I looked into using typedefs and soon changed those into alias', following Scott Meyers advice in "More effective C++".
I got one problem now which I can't seem to wrap my head around. Given the following two files (corresponding header and source file):
map.h:
class Map
{
public:
using tileLayerVector_t = std::vector<std::vector<Tile>>;
using rawDataLayerVector_t = std::vector<std::vector<int>>;
tileLayerVector_t getTileLayer(const std::string pLayerName) const;
void generateTileMapLayer(const std::string pMapLayerName, const rawDataLayerVector_t pRawMapData, const std::shared_ptr<Texture> pTexture);
}
map.cpp:
#include <map.h>
tileLayerVector_t Map::getTileLayer(const std::string pLayerName) const
{
return mapLayers.at(pLayerName);
}
void Map::generateTileMapLayer(const std::string pMapLayerName, const
rawDataLayerVector_t pRawMapData, const std::shared_ptr<Texture> pTexture)
{
int tileCount = 0;
int xPos = 0;
int yPos = 0;
...
std::pair<std::string, tileLayerVector_t> tileLayer(pMapLayerName, tileMapLayer);
mapLayers.insert(tileLayer);
}
Function generateTileMapLayer() compiles fine without a problem. As soon as I implement getTileLayer() the UI is giving me an error "identifier 'tileLayerVector_t' is undefined" and the compiler is giving me some weird error about a missing ";" somewhere. This compiler error vanishes if I put getTileLayer() in comments.
I don't understand why I can use the alias within the function generateTileMapLayer() as a type definition for the hash map, but cannot use it as a return type for getTileLayer(). I put Map::tileLayerVector_t as a return type and it works. Why does it work without the namespace within generateTileMapLayer() though?
Maybe someone can help me with this. Thank you in advance!
A class defines a scope. How you access something in a given scope depends on whether you are writing code that's inside or outside that scope.
So when you make the declaration using tileLayerVector_t = ...; within class Map you are providing an alias for a new type Map::tileLayerVector.
This is why your code inside the class can use the type without qualification, but code outside cannot.
You could move your using-declarations outside the class, but that would pollute the global namespace. A better solution, I think, would be to simply qualify the types where needed:
Map::tileLayerVector_t Map::getTileLayer(...) // must qualify type here
{
tileLayerVector_t temp = ...; // inside a class method, no problem here
}
A more modern solution would be to use "type inference". I believe you need at least a C++11 compliant compiler to take advantage of this feature. My understanding is that the trailing return type allows the compiler to defer establishing the actual type until after the function signature has been generated, at which point the scope has been established.
auto Map::getTileLayer(...) -> tileLayerVector_t
{
....
}

Using the STL stack as a member of a C++ class

I am working on a project that requires a list(singly) of stacks. I have made a class called "stacklist" that is just that, a list of stacks. I want the class to have a stack pointer that will point to the head of the list. However, I keep getting an error whenever I try to build the class.
#ifndef STACKLIST_H
#define STACKLIST_H
#include <stack>
//source: Data Structures Using C++: Linked List Implementation Part II (List Class)
//url: http://www.youtube.com/watch?feature=endscreen&NR=1&v=7vZo17iv1zQ
class stacklist
{
public:
stacklist();
void addToHead(const int&);
void printList();
void insert(const int&);
private:
stack<int>* head; //THIS IS WHERE I AM HAVING THE PROBLEM
int size;
};
#endif // STACKLIST_H
The error message is "error: expected ';' before '<' token"
Any insight that can be provided would be highly appreciated.
The standard library stack lives in the std namespace, so you need to qualify the name appropriately:
std::stack<int>* head;
You should consider using an std::list<std::stack<int>> instead of your class.
The correct name of the template is std::stack.
If all you want is a list of stacks, you could always use std::list<std::stack<int>>, by the way (or std::forward_list if you only need forward traversal). But even if you pursued your own design, there's probably no reason why you can't make the stack a direct class member.
Perhaps you should say std::stack
std::stack<int>* head; instead stack<int>* head;
If you're using std libraries, you must put std:: before the std object or place a using namespace std at the beggining of your source file:
#include <stack>
using namespace std; // This line brings std stuff into the current namespace.
Or:
std::stack<int>* head;
If your file is a header, it's better the first one than the second one because the using directive will be spreaded into all the files that includes StackList.h
This is no mentioned on the question, but I think is worth to say: Is quite dangerous to use pointers into classes, because you must take care of it into all constructors (default and copy) and take care on destructor too.
Revise your class dessign and think if you can use a std::stack instance instead of std::stack pointer.

Putting SDL surfaces in a map, along with file names

I'm very new to using maps in C++, so I am having some difficulties using it for my SDL surfaces. This is what I've tried (not working):
map <SDL_Surface*, char*> mSurfaceMap;
mSurfaceMap.insert(pair<SDL_Surface*, char*>(m_poSurfaceTest, "..//..//gfx//testImage.png"));
The idea is to put all surfaces and their corresponding image files in a map to easily initialize them and do IMG_Load() on them, as well as free them when closing the program.
If this is a bad solution for it, please point me in the right direction. I first thought of making two arrays, but I wanted to try this instead, as I felt it was a more elegant solution. If the solution is ok, I'd love to hear what I am doing wrong in the code.
This code works for me. Output is as expected:
#include <map>
#include <stdio.h>
using std::map;
using std::pair;
struct Custom
{
int val;
Custom() {val=0;}
};
int main(int argC,char* argV[])
{
map<Custom*,char*> mMap;
Custom* test = new Custom;
mMap.insert(pair<Custom*,char*>(test,"Test"));
printf("%s\n",mMap[test]);
return 0;
}
std::map is great for looking up data by an ordered key, it is usually implemented as a balanced binary tree that gives O(log n) look-up time. If the look-up order doesn't matter then a std::hash_map will be a better choice with an O(1) look-up time.
The problem with using a pointer as your key in either container is that the they will index by the integer address of the pointer, not the value of what is pointed to.
std::string, however, has value semantics and implements the less-than operator which will let the container index by the value of the string.
You may also want to put your surface in a smart pointer for memory management purposes.
typedef std::tr1::shared_ptr<SDL_Surface> surface_pointer;
typedef pair<std::string, surface_pointer > surface_pair;
std::map<std::string, surface_pointer > mSurfaceMap;
mSurfaceMap.insert(surface_pair("..//..//gfx//testImage.png", surface_pointer(m_poSurfaceTest)));
A couple of other thoughts...
If you don't need the look-up functionality, and are just using a container for housekeeping, then a simple std::vector<std::pair<std::string, SDL_Surface*> > would probably suffice for what you need.
Or, if you're storing the surfaces as members already (assuming from the variable name) then you could store the member variables as a tr1::unique_ptr<SDL_Surface> and when the containing class is deleted so will the SDL_Surface be deleted. For this to work however you need to provide a custom deallocator for the tr1::unique_ptr, that will teach it how to free an SDL_Surface*.
struct SdlSurfaceDeleter {
void operator() (SDL_Surface*& surface) {
if (surface) {
SDL_FreeSurface(surface);
surface = NULL;
}
}
};
Then you would specify your members like this (a typedef makes it less verbose):
typedef std::tr1::unique_ptr<SDL_Surface, SdlSurfaceDeleter> surface_ptr;
class MyClass {
public:
MyClass(const std::string& path)
: m_poSurfaceTest(IMG_Load(path.c_str()) { }
surface_ptr m_poSurfaceTest;
};

Inheriting List to Sortable List-protected members out of scope

I am developing a list in which I have used some protected variables count, entry[maxlist] etc.
List.h
class List
{
public:
//etc etc
protected:
int count;
int entry[maxlist];
};
Sortable_list.h
typedef Key Record;
class Sortable_list:public List<Record>
{
void selection_sort()
{
for(int position=count-1;position>0;i--) // Count is not declared in the scope
{
int max=max_key(0, position);
swap(max, position);
}
}
};
Is something wrong with inheriting the List to Sortable List? Why is it showing count out of scope?
#Edit: After seeing your whole code it becomes clearer. You're having ambiguities because of your includes, it will compile with msvc, because it handles such cases silently, but for g++ you should explicitly state that count is from this class, by doing this->count. You also had problems because of std::range_error, which could be avoided by removing using namespace std or replacing range_error with ::range_error which will indicate that you want the global scope. Another problem with your code is that, you were using an undefined variable i in your Sortable_list. The fixed code that compiles with g++ and msvc: http://codepad.org/7V70rNqf
I don't want to sound rude, but I strongly suggest you read a book on C++, your current code is very anti-idiomatic, and could be made generic with a smaller amount of code.
Why don't you use sort function template from <algorithm> header? All you need to write just one small Compare function.
Look like your List is not a template class, so List< Typename > doesn't exist ..
Also, you can use std::set<T> as a template class for sorted container => http://www.sgi.com/tech/stl/set.html