problem with template in extern .h and .cpp files

S

Stefan Bollmann

Hi,

i wonder about a problem with functions i cannot put out of my
main.cpp file into one *.h and *.cpp. When I run this little
testprogram:

#include <iostream>
#include <vector>
//#include"potential.h"
using namespace std;

template<class T>void test(T t);

template<class T>void test(T t)
{
cout << t << endl;
}

int main ()
{
cout << "Il sole splende!" << endl;
vector<vector<double> >A(2);
for (int i=0;i<A.size();i++)
A.resize(4,2);
test((double)5.);

return 0;
}

everything is well.
If i compile the following code everythings fine at first, too, but
running it produces a crash.
Code:

--- main.cpp ---

#include <iostream>
#include <vector>
#include"potential.h"
using namespace std;

int main ()
{
cout << "Il sole splende!" << endl;
vector<vector<double> >A(2);
for (int i=0;i<A.size();i++)
A.resize(4,2);
test((double)5.);

return 0;
}

--- potential.h ---

#include <iostream>
using namespace std;

template<class T>void test(T t);

--- potential.cpp ---

#include "potential.h"

template<class T>void test(T t)
{
cout << t << endl;
}

console:

myPC>g++ main.cpp potential.h potential.cpp
/usr/bin/ld: Undefined symbols:
void test<double>(double)
collect2: ld returned 1 exit status

I wonder about it, because if i don't use templates everything is fine
again:

--- potential.h ---

#include <iostream>
using namespace std;

void test(double t);

-- potential.cpp ---

#include "potential.h"

void test(double t)
{
cout << t << endl;
}

and the main.cpp like the second example.
What am I doing/thinking wrong?

Thanks for reading ;-) ,
Stefan
 
S

Stefan Naewe

Hi,

i wonder about a problem with functions i cannot put out of my
main.cpp file into one *.h and *.cpp. When I run this little
testprogram:

#include <iostream>
#include <vector>
//#include"potential.h"
using namespace std;

template<class T>void test(T t);

template<class T>void test(T t)
{
cout << t << endl;
}

int main ()
{
cout << "Il sole splende!" << endl;
vector<vector<double> >A(2);
for (int i=0;i<A.size();i++)
A.resize(4,2);
test((double)5.);

return 0;
}

everything is well.
If i compile the following code everythings fine at first, too, but
running it produces a crash.
Code:

--- main.cpp ---

#include <iostream>
#include <vector>
#include"potential.h"
using namespace std;

int main ()
{
cout << "Il sole splende!" << endl;
vector<vector<double> >A(2);
for (int i=0;i<A.size();i++)
A.resize(4,2);
test((double)5.);

return 0;
}

--- potential.h ---

#include <iostream>
using namespace std;

template<class T>void test(T t);

--- potential.cpp ---

#include "potential.h"

template<class T>void test(T t)
{
cout << t << endl;
}

console:

myPC>g++ main.cpp potential.h potential.cpp
/usr/bin/ld: Undefined symbols:
void test<double>(double)
collect2: ld returned 1 exit status

I wonder about it, because if i don't use templates everything is fine
again:

--- potential.h ---

#include <iostream>
using namespace std;

void test(double t);

-- potential.cpp ---

#include "potential.h"

void test(double t)
{
cout << t << endl;
}

and the main.cpp like the second example.
What am I doing/thinking wrong?

Thanks for reading ;-) ,
Stefan


Read this:
http://www.ensta.fr/~diam/c++/online/c++-faq-lite/templates.html#faq-35.12

S.
 
V

Victor Bazarov

Stefan said:
i wonder about a problem with functions i cannot put out of my
main.cpp file into one *.h and *.cpp. When I run this little
testprogram:
[..]

Please read the FAQ, the section on templates. Then look over
the rest of the FAQ for link errors, and such. That should answer
your concernes.

V
 
S

Stefan Bollmann

Ok, thx 2 all. The faq showed me the problem and now I know why I've
got a problem. Sry for not looking there..

Stefan
 
V

Vladimir Jovic

Shame said:
So, I'm experimenting with function objects (and Lambdas) and want to make a basic event/observer system. I created a class called Event, that takes a function definition as a template parameter (eg. void(int, int)) and then I allow observees to attach to the event
with the attach method, passing in a function object. The function objects are defined using boost::bind and boost::mem_fn. In the code below, there are two problems: (1) I cannot use overloaded functions in the event handler itself (hence they're called tock0,
tock1, tock2, etc.) and (2) I have to explicitly define the appropriate binding for the number of parameters. I've done this below using #define macros called Argument0 (no arguments), Argument1 etc.

So my question is this: is it possible to code it in such a way as both (1) and (2) dissapear? The code below should compile and run in a standard vs2010 console project. I don't know about g++.

Thanks.

#include <vector>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>

using namespace std;

template<class T>
class Event {

public:

void Attach(boost::function<T> f)
{
MyListeners.push_back(f);
}

void operator()() const
{
for_each(MyListeners.begin(), MyListeners.end(), [](boost::function<T> i) { i(); } );
}

template<class P>
void operator()(P p) const
{
for_each(MyListeners.begin(), MyListeners.end(), [p](boost::function<T> i) { i(p); } );
}

template<class P, class Q>
void operator()(P p, Q q) const
{
for_each(MyListeners.begin(), MyListeners.end(), [p, q](boost::function<T> i) { i(p, q); } );
}

template<class P, class Q, class R>
void operator()(P p, Q q, R r) const
{
for_each(MyListeners.begin(), MyListeners.end(), [p, q, r](boost::function<T> i) { i(p, q, r); } );
}

template<class P, class Q, class R, class S>
void operator()(P p, Q q, R r, S s) const
{
for_each(MyListeners.begin(), MyListeners.end(), [p, q, r, s](boost::function<T> i) { i(p, q, r, s); } );
}

Instead of all this, it is better to specialize class event for each
number of arguments. Then you do not need macros later on. Something
like this :

template < typename SignalType, int N >
class Event;

here specialize for each N

template<class T>
class Event< T, 0 > {
public:
void Attach(boost::function<T> f)
{
MyListeners.push_back(f);
}

void operator()() const
{
//call all callbacks
}

private:

std::vector<boost::function<T>> MyListeners;
};
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top