C++ template construction for class member lists - c++

So I have made a little bit of C++ templates before: some quite basic examples of the curiously recurring template pattern for classes of mathematical numbers. This time I tried using the same pattern to create a list or "network" for objects of a class which they could add themselves to and look around for other objects. I thought I could use a static std::list to do this. So my attempt goes like this:
template<class C> class HasNetwork{
public:
HasNetwork(){}
static list<C*> m;
};
template<class C> list<C*> HasNetwork<C>::m = list<C*>();
class IHaveNetwork: public HasNetwork<IHaveNetwork>{
public:
IHaveNetwork(){ m.push_back(this); }
};
int main(){
IHaveNetwork lHF, lHF2;
//for(list<IHaveNetwork*>::iterator it = lHF.m->begin(); ; it++);
return 0;
}
It seems to compile, but I get nasty link errors ( even with the for loop iterator commented out ). Maybe I need to do some cast or maybe "this" is not defined until after the constructor finishes?
Here is the link error:
/tmp/templatest-912860.o: In function `__clang_call_terminate':
templatest.cpp:
(.text.__clang_call_terminate[__clang_call_terminate]+0x9): undefined reference to `__cxa_begin_catch'
templatest.cpp:(.text.__clang_call_terminate[__clang_call_terminate]+0x12): undefined reference to `std::terminate()'
/tmp/templatest-912860.o: In function `__gnu_cxx::new_allocator<std::_List_node<IHaveNetwork*>
>::deallocate(std::_List_node<IHaveNetwork*>*, unsigned long)':
templatest.cpp:
(.text._ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE10deallocateEPS4_m[_ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE10deallocateEPS4_m]+0x1c): undefined reference to `operator delete(void*)'
/tmp/templatest-912860.o: In function `std::list<IHaveNetwork*, std::allocator<IHaveNetwork*>
>::_M_insert(std::_List_iterator<IHaveNetwork*>, IHaveNetwork* const&)':
templatest.cpp:
(.text._ZNSt4listIP12IHaveNetworkSaIS1_EE9_M_insertESt14_List_iteratorIS1_ERKS1_[_ZNSt4listIP12IHaveNetworkSaIS1_EE9_M_insertESt14_List_iteratorIS1_ERKS1_]+0x31): undefined reference to
`std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)'
/tmp/templatest-912860.o: In function `std::list >::_M_create_node(IHaveNetwork* const&)':
templatest.cpp:
(.text._ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_[_ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_]+0xa0): undefined reference to `__cxa_begin_catch'
templatest.cpp:(.text._ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_[_ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_]+0xbb): undefined reference to `__cxa_rethrow'
templatest.cpp:
(.text._ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_[_ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_]+0xce): undefined reference to `__cxa_end_catch'
/tmp/templatest-912860.o: In function `__gnu_cxx::new_allocator<std::_List_node<IHaveNetwork*> >::allocate(unsigned long, void const*)':
templatest.cpp:(.text._ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE8allocateEmPKv[_ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE8allocateEmPKv]+0x33): undefined reference to `std::__throw_bad_alloc()'
templatest.cpp:(.text._ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE8allocateEmPKv[_ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE8allocateEmPKv]+0x40): undefined reference to `operator new(unsigned long)'
/tmp/templatest-912860.o:(.eh_frame+0x13): undefined reference to `__gxx_personality_v0'

I cannot reproduce.
Here is a slightly modified version of you code that compiles links and runs without even a warning (I only had to fix some indirection level errors):
#include <iostream>
#include <list>
#include <string>
template<class C> class HasNetwork{
public:
HasNetwork(){}
static std::list<C*> m;
};
template<class C> std::list<C*> HasNetwork<C>::m = std::list<C*>();
class IHaveNetwork: public HasNetwork<IHaveNetwork>{
std::string name;
public:
IHaveNetwork(const std::string &name): name(name) { m.push_back(this); }
std::string getName() const {
return name;
}
};
int main(){
IHaveNetwork lHF("foo"), lHF2("bar");
for(std::list<IHaveNetwork*>::iterator it = lHF.m.begin(); it != lHF.m.end(); it++) {
std::cout << (*it)->getName() << std::endl;
}
return 0;
}

Related

Undefined reference with JsonBox functions

I am trying to follow the penguin programmer text-based rpg guide (http://www.penguinprogrammer.co.uk/rpg-tutorial/introduction/). I am working on the item class and I am having some undefined reference errors with JsonBox functions.
#include "Item.hpp"
#include "Entity.hpp"
#include "JsonBox/include/JsonBox.h"
//#include "EntityManager.hpp"
Item::
Item(std::string _id, std::string _name, std::string _description)
: Entity(_id) {
this->SetName(_name);
this->SetDescription(_description);
}
Item::
Item(std::string _id, JsonBox::Value& _v, EntityManager* _mgr)
: Entity (_id) {
this->Load(_v, _mgr);
}
void
Item::
Load(JsonBox::Value& _v, EntityManager* _mgr) {
JsonBox::Object o = _v.getObject();
this->SetName(o["name"].getString());
this->SetDescription(o["description"].getString());
return;
}
Then I am compiling this main.
//#include "EntityManager.cpp"
#include "Item.cpp"
#include "JsonBox/include/JsonBox.h"
int main() {
return 0;
}
And getting this error
/tmp/cc1sZXwe.o: In function `Item::Load(JsonBox::Value&, EntityManager*)':
main.cpp:(.text+0x286): undefined reference to `JsonBox::Value::getObject() const'
main.cpp:(.text+0x2d4): undefined reference to `JsonBox::Value::getString() const'
main.cpp:(.text+0x35c): undefined reference to `JsonBox::Value::getString() const'
/tmp/cc1sZXwe.o: In function `std::pair<std::string const, JsonBox::Value>::~pair()':
main.cpp: (.text._ZNSt4pairIKSsN7JsonBox5ValueEED2Ev[_ZNSt4pairIKSsN7JsonBox5ValueEED5Ev]+ 0x18): undefined reference to `JsonBox::Value::~Value()'
/tmp/cc1sZXwe.o: In function `std::pair<std::string const, JsonBox::Value>::pair(std::pair<std::string const, JsonBox::Value> const&)':
main.cpp: (.text._ZNSt4pairIKSsN7JsonBox5ValueEEC2ERKS3_[_ZNSt4pairIKSsN7JsonBox5ValueEEC5 ERKS3_]+0x3b): undefined reference to `JsonBox::Value::Value(JsonBox::Value const&)'
/tmp/cc1sZXwe.o: In function `std::pair<std::string const, JsonBox::Value>::pair<std::string&&, 0ul>(std::tuple<std::string&&>&, std::tuple<>&, std::_Index_tuple<0ul>, std::_Index_tuple<>)':
main.cpp: (.text._ZNSt4pairIKSsN7JsonBox5ValueEEC2IIOSsEILm0EEIEIEEERSt5tupleIIDpT_EERS6_I IDpT1_EESt12_Index_tupleIIXspT0_EEESF_IIXspT2_EEE[_ZNSt4pairIKSsN7JsonBox5ValueE EC5IIOSsEILm0EEIEIEEERSt5tupleIIDpT_EERS6_IIDpT1_EESt12_Index_tupleIIXspT0_EEESF _IIXspT2_EEE]+0x47): undefined reference to `JsonBox::Value::Value()'
Inside your main you include Item.cpp source file, changing your main to this might help you:
//#include "EntityManager.cpp"
#include "Item.hpp"
#include "JsonBox/include/JsonBox.h"
int main() {
return 0;
}
Including source files is usually a bad practice, and can cause many problems, you can read more about Including .cpp files

Cannot link object files because of undefined reference [duplicate]

This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Undefined reference error for template method [duplicate]
(3 answers)
Closed 9 years ago.
I cannot link object files. Compilation works fine, but the linker gives me these error messages:
testArguments.o: In function Z6__mainiPPc':
/cygdrive/c/Users/Lukas/work/ProxyServer/src/test/testArguments.cpp:5:
undefined reference toArguments::Arguments()'
/cygdrive/c/Users/Lukas/work/ProxyServer/src/test/testArguments.cpp:6:
undefined reference to Arguments<int>::insertItem(int)'
/cygdrive/c/Users/Lukas/work/ProxyServer/src/test/testArguments.cpp:8:
undefined reference to_Unwind_Resume' testArguments.o: In function
ZNSt10_List_baseIiSaIiEED2Ev':
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/bits/stl_list.h:378:
undefined reference to_Unwind_Resume' testArguments.o: In function
ZN9__gnu_cxx13new_allocatorISt10_List_nodeIiEE10deallocateEPS2_j':
/usr/lib/gcc/i686-pc-cygwin/4.8.2/include/c++/ext/new_allocator.h:110:
undefined reference tooperator delete(void*)'
testArguments.o:testArguments.cpp:(.eh_frame+0x13): undefined
reference to __gxx_personality_v0'
testArguments.o:testArguments.cpp:(.eh_frame$_ZNSt10_List_baseIiSaIiEED2Ev+0x13):
undefined reference to__gxx_personality_v0' Makefile:7: recipe for
target 'tests' failed
But these functions are defined in the cpp file (Argument::Arguments() Arguments::insertItem(int)
Here is my header file:
#ifndef ARGUMENTS_H
#define ARGUMENTS_H
#include <list>
using std::list;
template<class T>
class Arguments{
public:
Arguments(list<T> args);>
Arguments()>;
void insert>Item(T item);
list<T> getValues();
private:
list<T> values;
};
#endif
Here the cpp file:
#include "include/Arguments.h"
#include <list>
using std::list;
template<class T> Arguments<T>::Arguments(list<T> args) {
values = args;
}
template<class T> Arguments<T>::Arguments() {
}
template<class T> void Arguments<T>::insertItem(T argument){
values.push_back(argument);
}
template<class T> list<T> Arguments<T>::getValues() {
return this.values;
}

boost thread error <unresolved overloaded function type>

I'm working on an optimisation project and have decided to try threads to increase the speed of my code. the format of the code is:
Main.cpp:
int main(int argc, char **argv) {
B *b = new B(argv[1]);
b->foo();
delete b;
return EXIT_SUCCESS;
}
B.cpp:
#include B.hpp
B::B(const char *filename) { .... }
B::task1(){ /*nop*/ }
void B::foo() const {
boost::thread td(task1);
td.join();
}
B.hpp:
#include <boost/thread.hpp>
class B{
public:
void task1();
void foo();
}
however when I try to compile this code, I get an error at boost::thread td(task1), saying:
error: no matching function for call to 'boost::thread::thread(<unresolved overloaded function type>)'
not entirely sure what the problem is and I've tried hacking away to no success. Any help is appreciated!
edit: new error
B.o: In function 'B::b() const':
B.cpp:(.text+0x7eb): undefined reference to 'vtable for boost::detail::thread_data_base'
B.cpp:(.text+0x998): undefined reference to 'boost::thread::start_thread()'
B.cpp:(.text+0x9a2): undefined reference to 'boost::thread::join()'
B.cpp:(.text+0xa0b): undefined reference to 'boost::thread::~thread()'
B.cpp:(.text+0xb32): undefined reference to 'boost::thread::~thread()'
B.o: In function 'boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::cmf0<void, B>, boost::_bi::list1<boost::_bi::value<B const*> > > >::~thread_data()':
B.cpp:(.text._ZN5boost6detail11thread_dataINS_3_bi6bind_tIvNS_4_mfi4cmf0Iv4BEENS2_5list1INS2_5valueIPKS6_EEEEEEED2Ev[_ZN5boost6detail11thread_dataINS_3_bi6bind_tIvNS_4_mfi4cmf0Iv4BEENS2_5list1INS2_5valueIPKS6_EEEEEEED5Ev]+0x8): undefined reference to 'boost::detail::thread_data_base::~thread_data_base()'
B::task() is a member function, so it takes an implicit first parameter of type B*. So you need to pass an instance to it in order to use it in a boost::thread.
void B::foo() const {
boost::thread td(&B::task1, this); // this is a const B*: requires task1() to be const.
td.join();
}
But since B::foo() is a const method, you would have to make B::task1() a const method too:
class B {
void task1() const:
}

function invoking undefined reference

hi every one I have this class with those headers
class WuManber
{
public:
WuManber( void );
virtual ~WuManber( void );
void Initialize( const vector<const char *> &patterns,
bool bCaseSensitive = false, bool bIncludeSpecialCharacters = false, bool bIncludeExtendedAscii = false );
when I try try to create an instance of WuManber and invoke Initialize I get the following error:
/tmp/ccx19Os5.o: In function main': Test.cpp:(.text+0x8d): undefined
reference toWuManber::WuManber()' Test.cpp:(.text+0xbc): undefined
reference to WuManber::Initialize(std::vector<char const*,
std::allocator<char const*> > const&, bool, bool, bool)'
Test.cpp:(.text+0xc8): undefined reference toWuManber::~WuManber()'
Test.cpp:(.text+0x115): undefined reference to `WuManber::~WuManber()'
collect2: ld returned 1 exit status
int main(int argc, char* argv[])
{
Parser CustomParserEx;
CustomParserEx.open("/home/abdullah/Project IDS/rules");
WuManber WmAlgorithm;
WmAlgorithm.Initialize(CustomParserEx.patterns,true,true,true);
}
so any hints of what I am doing wrong
You didn't implement the three methods of WuManber, or you didn't include the implementations where the linker can find them.

Using gcc/g++ instrument functions with MinGW?

i try to use the gcc instrument functions with g++ compiler of MinGW, but i
always got linker issues. Is it possible to use the instrument functions with
MinGW/MSYS?
The linker failure output:
$ g++ instrumentFunctions.cpp -o iftest -finstrument-functions >> iflog.txt
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x4e): undefined reference to `__cyg_prof
ile_func_enter'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x158): undefined reference to `__cyg_pro
file_func_exit'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x179): undefined reference to `__cyg_pro
file_func_enter'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x18c): undefined reference to `__cyg_pro
file_func_exit'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x1a7): undefined reference to `__cyg_pro
file_func_enter'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x1bf): undefined reference to `__cyg_pro
file_func_exit'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x1db): undefined reference to `__cyg_pro
file_func_enter'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x1f3): undefined reference to `__cyg_pro
file_func_exit'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x22f): undefined reference to `__cyg_pro
file_func_enter'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x27a): undefined reference to `__cyg_pro
file_func_exit'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x29b): undefined reference to `__cyg_pro
file_func_enter'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x2e4): undefined reference to `__cyg_pro
file_func_exit'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x2ff): undefined reference to `__cyg_pro
file_func_enter'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x326): undefined reference to `__cyg_pro
file_func_exit'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x341): undefined reference to `__cyg_pro
file_func_enter'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x368): undefined reference to `__cyg_pro
file_func_exit'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text$printf[_printf]+0x16): undefined referenc
e to `__cyg_profile_func_enter'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text$printf[_printf]+0x43): undefined referenc
e to `__cyg_profile_func_exit'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text$_ZSt3minIjERKT_S2_S2_[unsigned int const&
std::min<unsigned int>(unsigned int const&, unsigned int const&)]+0x15): undefined reference to `__cyg_profile_func_ent
er'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text$_ZSt3minIjERKT_S2_S2_[unsigned int const&
std::min<unsigned int>(unsigned int const&, unsigned int const&)]+0x42): undefined reference to `__cyg_profile_func_exi
t'
collect2: ld returned 1 exit status
g++ command i use:
g++ iftest.cpp -o iftest -finstruction-functions
Listing of my testsource:
#include <stdio.h>
void __cyg_profile_func_enter( void *, void * ) __attribute__ ((no_instrument_function));
void __cyg_profile_func_enter(void *func, void *callsite)
{
printf("%p\n", (int)func);
}
void func_c( void )
{
return;
}
void func_b( void )
{
func_c();
return;
}
void func_a( void )
{
func_b();
return;
}
int main()
{
func_a();
func_c();
}
You need to give the __cyg* functions "C" linkage. A function defined in C++ normally gets a mangled name which can't be used from libraries not written in C++. You can ask the compiler to give a function the name C would give it by using an `extern "C"{} block. The following should compile fine.
#include <stdio.h>
extern "C" {
void __cyg_profile_func_enter( void *, void * ) __attribute__ ((no_instrument_function));
void __cyg_profile_func_enter(void *func, void *callsite)
{
printf("enter %p\n", func);
}
void __cyg_profile_func_exit( void *, void * ) __attribute__ ((no_instrument_function));
void __cyg_profile_func_exit(void *func, void *callsite)
{
printf("exit %p\n", func);
}
}
void func_c( void )
{
return;
}
void func_b( void )
{
func_c();
return;
}
void func_a( void )
{
func_b();
return;
}
int main()
{
func_a();
func_c();
}