I want to use the forward declaration for the ptree class of boost::property_tree.
I use Visual Studio 2010 and boost version 1.48.0.
I do the forward declaration in the following way, in my .h
#ifndef OPTIONS_H_
#define OPTIONS_H_
namespace boost
{
namespace property_tree
{
class ptree;
}
}
class Options
{
// something
private:
boost::property_tree::ptree *m_pxPropertyTree;
};
#endif // OPTIONS_H_
Then, I use the class inside my .cpp
#include <boost/property_tree/ptree.hpp>
using boost::property_tree::ptree;
Options::Options()
{
m_pxPropertyTree = new ptree();
// other stuff
}
when I try to compile it, I obtain the following error
error C2371: 'boost::property_tree::ptree': redefinition. Different base type. c:\lib\boost\1.48.0\32\boost\property_tree\ptree_fwd.hpp 95
(The error description can be different, I've translated it because I've the Italian version of Visual Studio).
The line that gives me the error, in ptree_fwd.hpp, is the following
typedef basic_ptree<std::string, std::string> ptree;
Instead, if I don't use the forward declaration, everything goes well and I compile it successfully.
What I'm doing wrong and how I can use correctly the forward declaration in this case?
Why don't you just include boost/property_tree/ptree_fwd.hpp? This header contains all forward declaration for the package.
Edit: The solution without the included (which you want to avoid for
good reasons) is to exactly match, what is actually declared.
So:
#include <string>
#include <functional>
namespace boost
{
namespace property_tree
{
template < class Key, class Data, class KeyCompare >
class basic_ptree;
typedef basic_ptree< std::string, std::string, std::less<std::string> > ptree;
}
}
Related
I have multiple C++ classes in a Pacman Game project (Maze, Food, Pacman, ...). I made a namespace 'Pacman_AI' so that the classes can be seen every where in the project. However, I got an error for 'GameObject' class: "name followed by '::' must be a class or namespace name".
Here is my "GameObject.cpp" in which I get the error above:
namespace Pacman_AI{
vector <pair <int, int> > GameObject::getPoints(){
return points;
}
string GameObject::getType(){
return type;
}
}
I already defined my "GameObject" class in a different file "GameObject.h".
Your help is highly appreciated.
The simplest thing is to use namespace in your header files
// Foo.h
namespace Pacman_AI{
// STUFF HERE
};
and then using namespace in your .cpp files
//Foo.cpp
#include "Foo.h"
using namespace Pacman_AI;
// define your functions here
I have a problem compiling multiple files with codeblocks. My problem is that the compiler doesnt recognize the class types that i created. I get the error doesnt name a type. I have add at all header files the #ifndef, #deffine. My files are:
forum.h
#include <list>
#include "thread.h"
class Forum
{
private:
std::list<Forum*> forums;
std::list<Thread*> themata;
}
thread.h
#include <list>
#include "forum.h"
#include "post.h"
class Thread
{
private:
Forum* forum; //gia tin allagi thesis otan ginei stick
int id;
std::list <Post*> lista;
}
post.h
#include "system.h"
class Post
{
private:
System* system;
}
What can i do for that ?
You have a circular header dependency. Use forward declarations to break it. For example, in forum.h, forward declare the Thread class instead of including its header like this:
#include <list>
class Thread;
class Forum
{
private:
std::list<Forum*> forums;
std::list<Thread*> themata;
};
Include the header in forum.cpp.
For some odd reason I am having difficulties throwing an exception in C++. I throw without catching std::invalid_argument from the stdexcept header file. I have no real intention of catching as i want the application to fail anyway if the error occurs.
It seemed to be working fine until I #included the function definition class into the namespace of the header declaration. It was added outside of the namespace prior since they are template definitions and I wanted to separate the header from its definition; however, I realized this caused a subtle issue that I did not realized until only recently.
Is their something I am missing? I am using clang btw
Project Compilation
.
.
.
.
.
Compiling CPP file TrieTest.cpp ...
In file included from TrieTest.cpp:4:
In file included from ./Trie.hpp:62:
In file included from ./Trie.cpp:2:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/stdexcept:55:30: error: unknown class name 'exception'; did you mean
'::std::exception'?
class logic_error : public exception
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/exception:60:9: note: '::std::exception' declared here
class exception
^
In file included from TrieTest.cpp:4:
In file included from ./Trie.hpp:62:
In file included from ./Trie.cpp:2:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/stdexcept:112:32: error: expected class name
class runtime_error : public exception
^
2 errors generated.
EDIT: A bit of the src
Also I compile with
clang++ -Wall -Wextra -g -std=c++11 TrieTest.cpp -o TrieTest;
"Trie.h"
#ifndef COM_WORDGAME_UTILITY_TRIE_HPP
#define COM_WORDGAME_UTILITY_TRIE_HPP
#include <string>
using std::string;
namespace wordgame_utility{
template<typename value>
class Trie{
...Trie Function Declarations
};
//The compiler may not complain initialliy however
//Templates cause visibility issues with user code and is normally defined in the header
//this is a work around
#include "Trie.cpp"
}
#endif
"Trie.cpp" head -n 8
#include "Trie.hpp"
#include <stdexcept>
using namespace wordgame_utility;
template<typename value>
using TrieNode = typename Trie<value>::TrieNode;
...Trie Function Definitions
You have a cyclic include in your code.
Trie.hpp includes Trie.cpp which includes Trie.hpp. This is not meant to work in C++, where include is a literal inclusion (think, copy/pasting the included file at the point of the #include directive).
You need to define template methods into the header, or into a third file, that's all there is.
What is the effect of this cycle ? In general, poor error messages, as you can see by yourself.
In your case... let's play preprocessor ourselves:
// begin #include "Trie.hpp"
#define COM_WORDGAME_UTILITY_TRIE_HPP
// begin #include <string>
namespace std {
...
}
// end #include <string>
using std::string;
namespace wordgame_utility{
template<typename value>
class Trie{
...Trie Function Declarations
};
//The compiler may not complain initialliy however
//Templates cause visibility issues with user code
// and is normally defined in the header
//this is a work around
// begin #include "Trie.cpp"
// begin #include "Trie.hpp"
// -- empty because of the include guards --
// end #include "Trie.hpp"
// begin #include <stdexcept>
namespace std {
class logic_exception: public exception { };
}
// end #include <stdexcept>
using namespace wordgame_utility;
template<typename value>
using TrieNode = typename Trie<value>::TrieNode;
...Trie Function Definitions
// end #include "Trie.cpp"
} // namespace wordgame_utility
// end #include "Trie.hpp"
As you can see, it's a mess. The combination of using #include within an open namespace and having cyclic includes is downright ugly.
Fortunately, in the (near ?) future, this will be improved if modules are adopted, which are just a much saner alternative to textual inclusion.
I was doing a project for computer course on programming concepts. This project was to be completed in C++ using Object Oriented designs we learned throughout the course. Anyhow, I have two files symboltable.h and symboltable.cpp. I want to use a map as the data structure so I define it in the private section of the header file. I #include <map> in the cpp file before I #include "symboltable.h".
I get several errors from the compiler (MS VS 2008 Pro) when I go to debug/run the program the first of which is:
Error 1 error C2146: syntax error : missing ';' before identifier 'table' c:\users\jsmith\documents\visual studio 2008\projects\project2\project2\symboltable.h 22 Project2
To fix this I had to #include <map> in the header file, which to me seems strange.
Here are the relevant code files:
// symboltable.h
#include <map>
class SymbolTable {
public:
SymbolTable() {}
void insert(string variable, double value);
double lookUp(string variable);
void init(); // Added as part of the spec given in the conference area.
private:
map<string, double> table; // Our container for variables and their values.
};
and
// symboltable.cpp
#include <map>
#include <string>
#include <iostream>
using namespace std;
#include "symboltable.h"
void SymbolTable::insert(string variable, double value) {
table[variable] = value; // Creates a new map entry, if variable name already exist it overwrites last value.
}
double SymbolTable::lookUp(string variable) {
if(table.find(variable) == table.end()) // Search for the variable, find() returns a position, if thats the end then we didnt find it.
throw exception("Error: Uninitialized variable");
else
return table[variable];
}
void SymbolTable::init() {
table.clear(); // Clears the map, removes all elements.
}
My guess is that you have another file that includes the header file #include "symboltable.h". And that other source file doesn't #include <map> nor #include <string> nor has using namespace std before it includes "symboltable.h".
Check which file is being compiled when you get the error. Is it maybe a different source file than the .cpp that you mentioned? Possibly something like main.cpp?
Another way to solve your problem is to put the includes you need in your header file and use std::map instead of simply map. Also you use string which is also inside the namespace std. So that needs to be std::string. And put the missing #include <string>.
Yes, you indeed have to #include <map> in the header file.
You use map in the declaration of the class, so the compiler needs to know what this map refers to. Since the definition of it is in <map> you need to include that header before using the map template class.
You could also instead #include <map> in every source file before the #include "symboltable.h" line, but usually you would just include these kind of prerequisites in the header.
Encountered this problem before but forgot how I solved it.
I want to use the STL string class but the complier is complaining about not finding it.
Here is the complete .h file.
#ifndef MODEL_H
#define MODEL_H
#include "../shared/gltools.h" // OpenGL toolkit
#include <math.h>
#include <stdio.h>
#include <string>
#include <iostream>
#include "Types.h"
class Model
{
public:
obj_type_ptr p_object;
char Load3DS (char *p_filename);
int LoadBitmap(char *filename);
int num_texture;
string fun("alex");
Model(char* modelName, char* textureFileName);
};
#endif
You want to be using std::string, yes?
You're just using string. Which works if you have a using namespace ... declaration, but isn't really a good idea in a header file.
Every identifier in the STL is in the std namespace. Until you do using namespace std;, using std::string;, or typedef std::string xxx;, it must be called std::string.
Any kind of using declaration in a header, especially outside your own namespace, is a bad idea, as others have mentioned.
So, import std::string into your class:
class Model
{
typedef std::string string;
public:
ohhh, std::string. Never use the using namespace in a header file btw.
As well as the namespace issue mentioned by other answers, you can't construct a variable at its declaration as a class member. Assuming you changed it to
class Model {
// ...
std::string fun("alex");
};
This is still illegal inside a class, you cannot assign a value in the declaration, you have to leave it:
class Model {
// ...
std::string fun;
};
And if you want to give it "alex" when it is created, initialise it in the constructor:
Model::Model(...)
: fun("alex") // initialiser
{
// ...
}