Template linking problem (multiple definition)

  • Thread starter Georg Teichtmeister
  • Start date
G

Georg Teichtmeister

Hello!

We are developing a math - library for realtime applications and want to
use some given mathlibraries as base(ipp, MTL, .. ). Our library is a
wrapper for those and you should be able to select the underlying
library by template parameter. Therefore we split up our library in two
namespaces:

The first one defines namespace-global functions which call the
baselibrary functions. These are templatefunctions which some
spezialitions for double and float.

The second one defines classes, where the functions of the first
namespace will be called.

Now comes the problem: If I include our mathlibrary into two
compilationunits the linker gives a error which says:

A.lo:in function Namespace1::ns_globalfunction:
A.lo:multiple definition of ns_globalfunction
B.lo:first defined here

And this comes for every namespaceglobal template function of the first
namespace for every spezialition.

regards,
Georg
 
G

Georg Teichtmeister

Georg said:
Hello!

We are developing a math - library for realtime applications and want to
use some given mathlibraries as base(ipp, MTL, .. ). Our library is a
wrapper for those and you should be able to select the underlying
library by template parameter. Therefore we split up our library in two
namespaces:

The first one defines namespace-global functions which call the
baselibrary functions. These are templatefunctions which some
spezialitions for double and float.

The second one defines classes, where the functions of the first
namespace will be called.

Now comes the problem: If I include our mathlibrary into two
compilationunits the linker gives a error which says:

A.lo:in function Namespace1::ns_globalfunction:
A.lo:multiple definition of ns_globalfunction
B.lo:first defined here

And this comes for every namespaceglobal template function of the first
namespace for every spezialition.

sorry, forgot to mention that I use gcc-2.95.3 and gcc-3.2
 
J

John Harrison

Georg Teichtmeister said:
Hello!

We are developing a math - library for realtime applications and want to
use some given mathlibraries as base(ipp, MTL, .. ). Our library is a
wrapper for those and you should be able to select the underlying
library by template parameter. Therefore we split up our library in two
namespaces:

The first one defines namespace-global functions which call the
baselibrary functions. These are templatefunctions which some
spezialitions for double and float.

The second one defines classes, where the functions of the first
namespace will be called.

Now comes the problem: If I include our mathlibrary into two
compilationunits the linker gives a error which says:

A.lo:in function Namespace1::ns_globalfunction:
A.lo:multiple definition of ns_globalfunction
B.lo:first defined here

And this comes for every namespaceglobal template function of the first
namespace for every spezialition.

regards,
Georg

Did you inline the fully specialised functions? I.e.

template <typename T>
void f(T x)
{
...
}

template <>
inline void f<double>(double x)
{
...
}

john
 
G

Georg Teichtmeister

Did you inline the fully specialised functions? I.e.

template <typename T>
void f(T x)
{
...
}

template <>
inline void f<double>(double x)
{
...
}

no, i write it like that:


template <typename T>
void f(T x)
{
...
}

template <>
void f(double x)
{
...
}
 
G

Georg Teichtmeister

Agent said:
<Georg Teichtmeister>
Now comes the problem: If I include our mathlibrary into two
compilationunits the linker gives a error which says:

A.lo:in function Namespace1::ns_globalfunction:
A.lo:multiple definition of ns_globalfunction
B.lo:first defined here

And this comes for every namespaceglobal template function of the first
namespace for every spezialition.
<Georg Teichtmeister>

You used a 'using namespace' somewhere and now
there is ambiguity between the global names and the
(same) names used in the namespace. You can help
it by prepending :: if you want the global version.

Namespace1::ns_globalfunction(); //namespaced version used
::ns_globalfunction(); //global version called

-X

sorry, i made a mistake, actually the error output is as the following:

A.lo:in function Namespace1::ns_globalfunction:
A.lo:multiple definition of Namespace1::ns_globalfunction
^^^^^^^^^^^^
B.lo:first defined here
 
A

Agent Mulder

<Georg Teichtmeister>
Now comes the problem: If I include our mathlibrary into two
compilationunits the linker gives a error which says:

A.lo:in function Namespace1::ns_globalfunction:
A.lo:multiple definition of ns_globalfunction
B.lo:first defined here

And this comes for every namespaceglobal template function of the first
namespace for every spezialition.
<Georg Teichtmeister>

You used a 'using namespace' somewhere and now
there is ambiguity between the global names and the
(same) names used in the namespace. You can help
it by prepending :: if you want the global version.

Namespace1::ns_globalfunction(); //namespaced version used
::ns_globalfunction(); //global version called

-X
 
A

Agent Mulder

Georg Teichtmeister said:
sorry, i made a mistake, actually the error output is as the following:

A.lo:in function Namespace1::ns_globalfunction:
A.lo:multiple definition of Namespace1::ns_globalfunction
^^^^^^^^^^^^
B.lo:first defined here


I misread your post. Sorry :-(
 
J

John Harrison

Georg Teichtmeister said:
no, i write it like that:


template <typename T>
void f(T x)
{
...
}

template <>
void f(double x)
{
...
}

Well that's why you get multiply defined errors. You need to inline the
fully specialised versions of your template functions.

john
 
G

Georg Teichtmeister

Georg said:
Hello!

We are developing a math - library for realtime applications and want to
use some given mathlibraries as base(ipp, MTL, .. ). Our library is a
wrapper for those and you should be able to select the underlying
library by template parameter. Therefore we split up our library in two
namespaces:

The first one defines namespace-global functions which call the
baselibrary functions. These are templatefunctions which some
spezialitions for double and float.

The second one defines classes, where the functions of the first
namespace will be called.

Now comes the problem: If I include our mathlibrary into two
compilationunits the linker gives a error which says:

A.lo:in function Namespace1::ns_globalfunction:
A.lo:multiple definition of ns_globalfunction
B.lo:first defined here

And this comes for every namespaceglobal template function of the first
namespace for every spezialition.

regards,
Georg

now I have a coding example which produces the error I have:

FILE: output.h
#include <iostream>

#ifndef TEST_H
#define TEST_H

namespace Test
{
template<typename T>
void test(T output)
{
std::cout << output << std::endl;
}

template<> void test<int>(int output)
{
std::cout << "Int: " << output << std::endl;
}

}


#endif


FILE: class1.h

#include "output.h"

class class1
{
public:
class1();
};


FILE: class1.cpp

#include "class1.h"

class1::class1()
{
Test::test<int>(13);
}

FILE: class2.h

#include "class1.h"

class class2 : public class1
{
public:
class2();
};


FILE: class2.cpp

#include "class2.h"

class2::class2()
{
Test::test<unsigned int>(34);
}

FILE: testTemplate.cpp

#include "class2.h"

int main(int argc, char** argv)
{
class1 c1;
class2 c2;


}

This is the error output from the linker:

class2.o: In function `void Test::test<int>(int)':
class2.o(.text+0x0): multiple definition of `void Test::test<int>(int)'
class1.o(.text+0x0): first defined here
testTemplate.o: In function `void Test::test<int>(int)':
testTemplate.o(.text+0x0): multiple definition of `void
Test::test<int>(int)'
class1.o(.text+0x0): first defined here
collect2: ld returned 1 exit status

Compiler: gcc-2.95.3

regards,
Georg
 
G

Georg Teichtmeister

Well that's why you get multiply defined errors. You need to inline the
fully specialised versions of your template functions.

john
it works with my sample program, lets try it for the lib :)

thank you
 
J

John Harrison

now I have a coding example which produces the error I have:

FILE: output.h
#include <iostream>

#ifndef TEST_H
#define TEST_H

namespace Test
{
template<typename T>
void test(T output)
{
std::cout << output << std::endl;
}

template<> void test<int>(int output)

Try this

template said:
{
std::cout << "Int: " << output << std::endl;
}

}

john
 
G

Geoff Macartney

John

why is that? what difference logically does the inline make?
Is this just a feature of gcc? or is it to do with the inline making the
definition appear only in the compilation unit it's included in?
Is this just a feature for specialised functions or does it apply to
all template functions?

Geoff
 

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,570
Members
45,045
Latest member
DRCM

Latest Threads

Top