I have started working on a project that incorporates some of boost libraries(thread and MPI).
I am going to use boost multi_index in one of the modules which is not using boost at all.FYI this project has not used boost multi index before)
as soon as I tried to include
boost/multi_index_container.hpp
to the file and built the projects, I received a number of errors starting with the following:
Building CXX object CMakeFiles/SimMobility.dir/main.cpp.o
/usr/bin/c++ -fmessage-length=0 -DBOOST_NO_HASH -O0 -g -I/usr/include/postgresql -I/usr/include/soci -I/usr/include/soci/postgresql -I/usr/include/xsd -I/home/vahid/workspace/Basic__Multi_index -o CMakeFiles/SimMobility.dir/main.cpp.o -c /home/vahid/workspace/Basic__Multi_index/main.cpp
In file included from /usr/include/boost/multi_index/detail/node_type.hpp:22:0,
from /usr/include/boost/multi_index/detail/index_base.hpp:21,
from /usr/include/boost/multi_index/detail/base_type.hpp:21,
from /usr/include/boost/multi_index_container.hpp:33,
from /home/vahid/workspace/Basic__Multi_index/geospatial/RoadNetwork.hpp:10,
from /home/vahid/workspace/Basic__Multi_index/main.cpp:25:
/usr/include/boost/multi_index/detail/header_holder.hpp:41:16: error: expected unqualified-id before ‘)’ token
/usr/include/boost/multi_index/detail/header_holder.hpp: In constructor ‘boost::multi_index::detail::header_holder<NodeTypePtr, Final>::header_holder()’:
/usr/include/boost/multi_index/detail/header_holder.hpp:35:32: error: expected primary-expression before ‘)’ token
may I know what the problem is? is it cmake not finding what it needs? any idea how to solve it?
Edit:
in case you want to have a look at the source code, here is a simplified version:
RoadNetwork.hpp:
#pragma once
#include <iostream>
#include <vector>
#include <set>
#include <boost/multi_index_container.hpp> //causing problem!!!!!!!
namespace geo {class Links_pimpl;}
namespace sim_mob
{
//Forward declarations
class Node;
class UniNode;
class MultiNode;
class Point2D;
class Link;
namespace aimsun
{
//Forward declaration
class Loader;
}
//typedef multi_index_container<
//sim_mob::Link,
// indexed_by<
// random_access<>,
//// ordered_unique< member<sim_mob::Link, std::string, &sim_mob::Link::linkID> >
// >
//> Link_m;
class RoadNetwork {
public:
RoadNetwork() { drivingSide=DRIVES_ON_LEFT; } //TEMP
sim_mob::Node* locateNode(const sim_mob::Point2D& position, bool includeUniNodes=false, int maxDistCM=100) const;
private:
std::vector<sim_mob::MultiNode*> nodes;
std::vector<sim_mob::Link*> links;
std::vector<sim_mob::MultiNode*>& getNodesRW() { return nodes; }
std::set<sim_mob::UniNode*>& getUniNodesRW() { return segmentnodes; }
std::vector<sim_mob::Link*>& getLinksRW() { return links; }
friend class sim_mob::aimsun::Loader;
friend class geo::Links_pimpl;
};
}
Thank you your kind help
vahid
I modified your header to look like this:
#pragma once
#include <iostream>
#include <vector>
#include <set>
#include <boost/multi_index_container.hpp> //causing problem!!!!!!!
using boost::multi_index_container;
namespace geo {class Links_pimpl;}
namespace sim_mob
{
//Forward declarations
class Node;
class UniNode;
class MultiNode;
class Point2D;
class Link;
namespace aimsun
{
//Forward declaration
class Loader;
}
//typedef multi_index_container<
//sim_mob::Link,
// indexed_by<
// random_access<>,
// ordered_unique< member<sim_mob::Link, std::string, &sim_mob::Link::linkID> >
// >
//> Link_m;
class RoadNetwork {
int drivingSide;
enum side { DRIVES_ON_LEFT, DRIVES_ON_RIGHT};
public:
RoadNetwork() { drivingSide=DRIVES_ON_LEFT; } //TEMP
sim_mob::Node* locateNode(const sim_mob::Point2D& position, bool includeUniNodes=false, int maxDistCM=100) const;
private:
std::vector<sim_mob::MultiNode*> nodes;
std::vector<sim_mob::Link*> links;
std::set<sim_mob::UniNode*> segmentnodes;
std::vector<sim_mob::MultiNode*>& getNodesRW() { return nodes; }
std::set<sim_mob::UniNode*>& getUniNodesRW() { return segmentnodes; }
std::vector<sim_mob::Link*>& getLinksRW() { return links; }
friend class sim_mob::aimsun::Loader;
friend class geo::Links_pimpl;
};
}
Then I included it in a small file that instantiated a RoadNetwork object:
#include <iostream>
#include "roadnetwork.hpp"
int main() {
sim_mob::RoadNetwork roads;
return 0;
}
This compiled, linked, and executed (though produced no output).
Not entirely sure what problem you're encountering...
I encountered the same problem and tracked it down. Do you have by chance a #define final somewhere in your sources before including boost/multi_index.hpp or a -Dfinal in your compiler settings? In my case that was the problem, I use the C++11 keywords final and override in my classes and had to define them when using older compilers.
Or, maybe it's some other identifier used by multi_index that you have defined somewhere. You could dump all your defined macros as described here and check if disabling one of them helps.
I also encountered similar problem.
I got compile error in
multi_index header_holder file.
warning : final key word is blah... blah...
So I changed the
#include <boost/xxxxx>
position to other place.
( ex: stdafx.h etc ... )
Try this one.
Related
First I would like to show the working code and then explain, how i want to change things. This is simple boost multi_index example:
//main.cpp
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/member.hpp>
#include <string>
struct employee
{
int id;
std::string name;
employee(int id, const std::string& name) :id(id), name(name){}
bool operator<(const employee& e)const{ return id<e.id; }
};
typedef boost::multi_index::multi_index_container<
employee,
boost::multi_index:: indexed_by<
// sort by employee::operator<
boost::multi_index:: ordered_unique< boost::multi_index:: identity<employee> >,
// sort by less<string> on name
boost::multi_index::ordered_non_unique<boost::multi_index::member<employee, std::string, &employee::name> >
>
> employee_set;
int main()
{
employee_set es;
es.insert(employee(0, "Bob"));
}
Imagine if main.cpp is another module, without boost dependency. I want to udnerstand how to:
include some header file with boost multiindex container class being forward declared into main.cpp
define multiindex container of employees in additional .cpp file
I have tried tons of variants, but none if this works. Is it possible to create something like this?
//notmain.cpp
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/member.hpp>
#include "notmain.h"
typedef boost::multi_index::multi_index_container<
employee,
boost::multi_index::indexed_by<
// sort by employee::operator<
boost::multi_index::ordered_unique< boost::multi_index::identity<employee> >,
// sort by less<string> on name
boost::multi_index::ordered_non_unique<boost::multi_index::member<employee, std::string, &employee::name> >
>
> employee_set;
Now comes h.file I need to fill with forward declaration (or explicit initiation) of container. I may be misunderstanding these terms, but I am new to c++ and boost.
//notmain.h
#include <string>
/*
Some how here I need forward declaration or explicit initiation of boost container
class employee_set ???
*/
struct employee
{
int id;
std::string name;
employee(int id, const std::string& name) :id(id), name(name){}
bool operator<(const employee& e)const{ return id<e.id; }
};
This is final goal. I want to remind that main.cpp is imagined to be .cpp of another module, without boost dependency.
//main.cpp
#include "notmain.h"
int main()
{
employee_set es;
es.insert(employee(0, "Bob"));
}
If the type is part of a class' visible interface then any headers that class is dependent on have to be included, no way around that. If you really don't want it to be part of the visible interface consider using the pImpl idiom:
Public header
#if !defined(MYCLASS_PUBLIC_H_)
#define MYCLASS_PUBLIC_H_
struct MyClassImpl;
class MyClass {
MyClassImpl * pImpl;
public:
void SomeOperation();
};
#endif
Implementation header:
#if !defined(MYCLASS_IMPL_H_)
#define MYCLASS_IMPL_H_
#include <private_type.h>
#include "MyClass.h"
struct MyClassImpl
{
void Operation();
private:
SomePrivateType member;
};
#endif
Implementation file:
#include "MyClassImpl.h"
void MyClass::SomeOperation()
{
pImpl->Operation();
}
void MyClassImpl::Operation()
{
// do something with 'member'
}
Code that only sees the public interface:
#include "MyClass.h"
void foo()
{
MyClass inst;
inst.SomeOperation();
}
I am sure this is a trivial error. Nontheless I cannot find an error or a solution on Stackoverflow.
I have received above mentioned error for struct Transition, seemingly declared here :
Transition.h:
#ifndef ZOCK_TRANSITION_H
#define ZOCK_TRANSITION_H
#include <iostream>
#include "vec.h"
#include "dir.h"
#include "Board.h"
using std::ostream;
using std::endl;
struct Transition
{
vec fromv;
dir fromd;
vec tov;
dir tod;
Transition();
Transition(vec fromv, dir fromd, vec tov, dir tod);
friend ostream& operator<< (ostream& os, cost Transition& t);
};
Transition swap(Transition& t) const;
#endif// ZOCK_TRANSITION_H
Error Message is :
g++ -std=c++14 -I./inc -c src/Transition.cpp -o build/debug/Transition.o -g3
In file included from ./inc/Board.h:21:0,
from ./inc/Transition.h:19,
from src/Transition.cpp:12:
./inc/Map.h:29:9: error: ‘Transition’ was not declared in this scope
vector<Transition> transitions;
So lets look into Map.h:
#ifndef ZOCK_MAP_H
#define ZOCK_MAP_H
#include <string>
#include <vector>
#include "Transition.h"
using std::string;
using std::vector;
class Map
{
friend class Board;
private:
int height, width;
char ** fields;
vector<Transition> transitions;
public:
enum readfrom
{
str = 0,
file ,
NUM_READFROM //Leave last !
};
Map(string i, readfrom p);
};
#endif// ZOCK_MAP_H
It is unlikely that it is a compiler or linker error, since it seems every file was found correctly. Everything seems to be included correctly, so I am at a dead end.
What dows cause the error or what are common mistakes causing the error ?
so at the moment I am trying to run a method within a <translator> class, by passing it an instance of a <bintree> class from my main.cpp. The following is my code, with the error that I am recieveing on the bottom. Im sure I am just missing some aspect to passing parameters, but for the life of me I cannot figure it out.
main.cpp (area where it creates bintree and where it is passed) bottom line most relevant
if (validFile == true)
{
//Create bintree through insert. Rebalance follows
bintree<morseNode> morseTree;
for (int count = 0; count < 26; count++)
{
char letter = morseCodes[count].letter;
string code = morseCodes[count].code;
morseNode node;
node.letter = letter;
node.code = code;
morseTree.insert(node);
}
morseTree.rebalance();
translator fileTranslator(outputFile);//create instance of translator
//Read and translate files based on conversion type
if (translatorType != "e" || translatorType != "E") //English -> Morse Conversion
{
validFile = readFile(inputFile, translatorType, morseCodes, inputList);
if (validFile == true)
{
fileTranslator.engToMorseTranslation(inputList, morseCodes);
}
}
else //Morse -> English Conversion
{
validFile = readFile(inputFile, translatorType, morseCodes, inputList);
if (validFile == true)
{
fileTranslator.morseToEngTranslation(inputList, morseTree);
//Here is where it sends morseTree that is throwing ^^ the error.
}
}
I am receiving it through translator.h (edit: it knows the consts for morseNode)
#ifndef TRANSLATOR_H
#define TRANSLATOR_H
#include <string>
#include <iostream>
#include <list>
//I tried #include "bintree.h" here. this did not work
using namespace std;
class translator
{
private:
string outName;
list<char> morseOutput;
public:
void morseToEngTranslation(list<char> &myList, bintree<morseNode> &myTree)
{
//functions here.. seemed irrelevant as i just wanted to show how i am
//receiving the parameters
}
};
#endif
bintree is not mine, it was provided. the starting declarations as follows. It is very long so and the functions themselves are not important for this issue, so i wont include them.
#ifndef BINTREE_H_
#define BINTREE_H_
#include <stdexcept>
namespace treespc
{
// forward class declaration
template <typename dataType> class bintree;
template <typename dataType> class binnode;
#include "const_iterator.h"
#include "binnode.h"
/********************************************************\
template class for a binary tree
\********************************************************/
template <typename dataType> class bintree
{
public:
//....
private:
//....
};
}
and the errors i receive are:
translator.h:79:52: error: ‘bintree’ has not been declared
void morseToEngTranslation(list<char> &myList, bintree<morseNode> &myTree)
translator.h:79:59: error: expected ‘,’ or ‘...’ before ‘<’ token
void morseToEngTranslation(list<char> &myList, bintree<morseNode> &myTree)
thank you in advance to anyone who can at least point me in the right direction :)
Give the namespace for bintree, either using using namespace treespec or treespc::bintree
#ifndef TRANSLATOR_H
#define TRANSLATOR_H
#include <string>
#include <iostream>
#include <list>
#include "bintree.h"
using namespace std;
class translator
{
private:
string outName;
list<char> morseOutput;
public:
void morseToEngTranslation(list<char> &myList, treespc::bintree<morseNode> &myTree)
{
//functions here.. seemed irrelevant as i just wanted to show how i am
//receiving the parameters
}
};
#endif
ifndef BINTREE_H_
#define BINTREE_H_
Are you missing a # here?
UPDATE: You must include bintree header or use forward declaration (be careful as your class is inside the namespace) See answers here :Why can't I forward-declare a class in a namespace like this?
Below I have reproduced a simplified version of a part of my code that gives error when compiling.
testing.cpp
#include <iostream>
#include "../Beta.h"
#include "../Alpha.h"
using namespace std;
int main() {
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
return 0;
}
Alpha.h
#include <vector>
class Alpha
{
public:
typedef struct _info{
int k;
} info;
friend class Beta;
};
Beta.h
#include <vector>
class Alpha;
class Beta
{
public:
std::vector <Alpha::info*> vecInfo;
};
When I run g++ testing.cpp I get below error message
In file included from testing.cpp:10:0: ../Beta.h:8:15: error:
incomplete type ‘Alpha’ used in nested name specifier ../Beta.h:8:15:
error: incomplete type ‘Alpha’ used in nested name specifier
../Beta.h:8:27: error: template argument 1 is invalid ../Beta.h:8:27:
error: template argument 2 is invalid
I can see from the forum threads that the first error is because of some kind of cyclic dependency (Error: incomplete type used in nested name specifier). I am unable to see similarity between my code and their code. What am I doing wrong.
This is not really a circular dependency. Beta.h just needs to #include "Alpha.h" instead of forward-declaring class Alpha;.
You need to include Alpha.h in Beta.h, because the full class definition is needed to have access to Alpha::info. This will not create a cyclic dependency because Alpha.h does not include Beta.h.
// don't forget the include guards!
#ifndef BETA_H_
#define BETA_H_
#include <vector>
#include "../Alpha.h"
class Beta
{
public:
std::vector <Alpha::info*> vecInfo;
};
#endif
I have the following three files in the same directory:
citysim.cpp
#include "utils.h"
using namespace std;
int main()
{
City *c;
c = new City();
Graph<City *> g;
g.addVertex(c);
}
utils.h
#include <iostream>
#include <map>
#include <vector>
using namespace std;
class City {
public:
City() {}
private:
string name;
};
template <typename Tkey>
class Graph {
public:
Graph() {}
void addVertex(Tkey);
private:
vector<Tkey> v;
vector< vector<int> > e;
map<Tkey, int> key_map;
};
utils.cpp
#include "utils.h"
template <typename Tkey>
void Graph<Tkey>::addVertex(Tkey vertex)
{
v.push_back(vertex);
}
And I am really perplexed as to why the following compilation sequence produces the result indicated:
test> g++ -c citysim.cpp
test> g++ -c utils.cpp
test> g++ -o citysim citysim.o utils.o
citysim.o: In function `main':
citysim.cpp:(.text+0x4a): undefined reference to `Graph<City*>::addVertex(City*)'
collect2: ld returned 1 exit status
Any ideas or insights are appreciated!
Define everything of your templated class in your header file, not in a cpp file. Instead of having your utils.cpp have everything like this in your header file:
template <typename Tkey>
class Graph {
public:
Graph() {}
void addVertex(Tkey vertex)
{
v.push_back(vertex);
}
private:
vector<Tkey> v;
vector< vector<int> > e;
map<Tkey, int> key_map;
};
Here is the related reading in the faq...
EDIT:
(But you can define it later on like you did it in your cpp in the header file as well...)
Template functions must be written entirely on the header, their definitions can't go on the cpp file.