Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: template in error

6 views
Skip to first unread message
Message has been deleted

Stephan Brönnimann

unread,
Jan 14, 2006, 9:55:03 AM1/14/06
to
eiji wrote:
> Hi folks,
>
> I have a linker - problem using a Matrix-template.
> Maybe someone can help me with that.
>
> Q:
> "using femath::Matrix" or "using femath::Matrix<double>";

using femath::Matrix;

>
> Consider this:
>
> ##########################
> namespace femath {
> ...
> template<class T> class Matrix
> {
> public:
> Matrix();
> Matrix(int rows);
> Matrix(int rows, int columns);
> virtual ~Matrix();
> ...
> };
> } //end namespace
>
> namespace fesolv {
>
> using femath::Matrix;
>
> class AbstractSolver
> {
> public:
> AbstractSolver(Model* model);
> virtual ~AbstractSolver();
>
> public:
> virtual void Solve()=0;
> ...
> protected:
> Model* _model;
> Matrix<double>* _systemstiffnessmatrix;
> ...
> };
>
> } //end namespace
>
> ##########################
>
> Everything compiles great but the linker tells me:
> AbstractSolver.obj : error LNK2019: unresolved external symbol "public:
> __thiscall femath::Matrix<double>::Matrix<double>(int)"

The constructor
template<typename T> Matrix<T>::Matrix(int);
is not implemented ...

> (??0?$Matrix@N@femath@@QAE@H@Z) referenced in function "public:
> __thiscall fesolv::AbstractSolver::AbstractSolver(class fesolv::Model
> *)" (??0AbstractSolver@fesolv@@QAE@PAVModel@1@@Z)

... and it is called from the constructor of fesolv::AbstractSolver.

Regards, Stephan

Message has been deleted

TB

unread,
Jan 14, 2006, 10:33:18 AM1/14/06
to
eiji sade:
> That is clear. The constructor is called but not found. So why?
> template<class T> Matrix<T>::Matrix(int)
> {
> ...
> }
> exists!
>

But where?

> Is there a "template<T>" phrase missing?
> What can be the problem?
>

TB

Message has been deleted

TB

unread,
Jan 14, 2006, 11:03:13 AM1/14/06
to
eiji sade:
> I tried this:
<snip>
> but handling it this way:
> #######
> //a.h
> namespace test {
>
> template<class T> class Test
> {
> T i;
> public:
> Test(T t);
>
> };
> }
> #####
> //a.cpp
> #include "a.h"
> namespace test {
>
> template<class T> Test<T>::Test(T t)
> {
> i = t;
> }
>
> }
<snip>
>
> same error, the constructor is not found!
> Any important linker-options?
>
> Sorry, any suggestions?
> Sascha
>

Compiler limitations. The template declarations and definitions must
be in the same translation unit.

Other solutions:
* Read about support for the 'export'-keyword for you compiler.
* #include the cpp-file after the declarations in the header-file.

TB

Ben Pope

unread,
Jan 14, 2006, 11:04:45 AM1/14/06
to
eiji wrote:
> Hi folks,
>
> I have a linker - problem using a Matrix-template.
> Maybe someone can help me with that.


class Model;

namespace femath {


template<class T> class Matrix
{
public:
Matrix();
Matrix(int rows);
Matrix(int rows, int columns);
virtual ~Matrix();

};
} //end namespace

namespace fesolv {

using femath::Matrix;

class AbstractSolver
{
public:
AbstractSolver(Model* model);
virtual ~AbstractSolver();

public:
virtual void Solve()=0;
protected:
Model* model_;
Matrix<double>* systemstiffnessmatrix_;
};
}

int main(int argc, char* argv[])
{
}

Works for me.

Ben Pope
--
I'm not just a number. To many, I'm known as a string...

Message has been deleted

Ben Pope

unread,
Jan 14, 2006, 1:04:30 PM1/14/06
to
eiji wrote:
> I tried this:
>
> //main.cpp

> namespace test {
>
> template<class T> class Test
> {
> T i;
> public:
> Test(T t);
>
> };
>
> template<class T> Test<T>::Test(T t)
> {
> i = t;
> }
>
> }
> int main(int argc , char *argv[])
> {
> using namespace test;
> Test<int> T(1);
> return 0;
> }
> #######
>
> Compiles and links without problems!

>
> but handling it this way:
> #######
> //a.h
> namespace test {
>
> template<class T> class Test
> {
> T i;
> public:
> Test(T t);
>
> };
> }
> #####
> //a.cpp
> #include "a.h"
> namespace test {
>
> template<class T> Test<T>::Test(T t)
> {
> i = t;
> }
>
> }
> //main.cpp
> #include "a.h"
> int main(int argc , char *argv[])
> {
> using namespace test;
> Test<int> T(1);
> return 0;

> }
>
> same error, the constructor is not found!
> Any important linker-options?

Test is a template, so the compiler must be able to see the definition.

http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12

Message has been deleted
0 new messages