Passing template struct as an argument to a template function

N

nifsmith

Hi

I am trying to learn about Queues and use templates at the same time. I
have written the following code and I am getting a link error, stating

"unresolved external symbol, "int__cdecl adsq::QInitialise<struct
adsq::Data>(struct adsq::Head<struct adsq::Data> *)"

-----------adsq.h file

#ifndef ADSQ_H

#define ADSQ_H

#include <iostream>

namespace adsq
{
struct Data
{
int First;
int Second;
};

template <class T> struct Node
{
T itsData;
Node<T>* nextNode;
};

template <class T> struct Head
{
Node<T>* itsHead;
Node<T>* itsTail;
long Count;
];

template <class R> int QInitialise(Head<R>* theQueueHead);
//Specialiasation
//template <> int QInitialise(Head<Data>* theQueueHead);
}

-----------adsq.cpp

#include "adsq.h"

template <class R> int adsq::QInitialise(Head<R>* theQueueHead)
{
theQueueHead->itsHead = 0;
theQueueHead->itsTail = 0;
theQueueHead->Count = 0;
}

//template <> int adsq::QInitialise(Head<Data>* theQueueHead)
//{
//theQueueHead->itsHead = 0;
//theQueueHead->itsTail = 0;
//theQueueHead->Count = 0;
//}

-----------driver.h

#ifndef DRIVER_H

#define DRIVER_H

#include <iostream>

#include "adsq.h"

#endif

-----------driver.cpp

#include "driver.h"

using namespace std;
using namespace adsq;

int main()
{
Head<Data> *pH = new Head<Data>;
int i = QInitialise(pH); //This will only work if you implement
//the specialisation
}

I have tried to keep this as simple for myself as possible as I am still
new to this C++ game.

I have tried the FAQ and googling, but I can't find anything specific to
passing templates to templates

Can you pass a template to another template as I am trying to do above,
or is it not possible. Must I use specialisations, if I do how will I
know ever type that a user may put into my queue?

The above was created in a VS 2003 unmanaged project.

TYIA

nifsmith
 
J

John Harrison

nifsmith said:
Hi

I am trying to learn about Queues and use templates at the same time. I
have written the following code and I am getting a link error, stating

"unresolved external symbol, "int__cdecl adsq::QInitialise<struct
adsq::Data>(struct adsq::Head<struct adsq::Data> *)"
[snip]

I have tried to keep this as simple for myself as possible as I am still
new to this C++ game.

I have tried the FAQ and googling, but I can't find anything specific to
passing templates to templates

Can you pass a template to another template as I am trying to do above,
or is it not possible. Must I use specialisations, if I do how will I
know ever type that a user may put into my queue?

The problem is covered in the FAQ but it has nothing to do with passing
templates to templates (which is perfectly OK). The problem is that template
code must always go in header files, take all the code from adsq.cpp and put
it in adsq.h. See the FAQ
http://www.parashift.com/c++-faq-lite/containers-and-templates.html#faq-34.12 and following.

john
 
N

nifsmith

John said:
The problem is covered in the FAQ but it has nothing to do with passing
templates to templates (which is perfectly OK). The problem is that template
code must always go in header files, take all the code from adsq.cpp and put
it in adsq.h. See the FAQ
http://www.parashift.com/c++-faq-lite/containers-and-templates.html#faq-34.12 and following.

john

Here I stand chastened and contrite.

I now intend to read everything in the FAQ

Many thanks

nifsmith.
 
M

Maitre Bart

John Harrison said:
nifsmith said:
Hi

I am trying to learn about Queues and use templates at the same time. I
have written the following code and I am getting a link error, stating

"unresolved external symbol, "int__cdecl adsq::QInitialise<struct
adsq::Data>(struct adsq::Head<struct adsq::Data> *)"
[snip]

I have tried to keep this as simple for myself as possible as I am still
new to this C++ game.

I have tried the FAQ and googling, but I can't find anything specific to
passing templates to templates

Can you pass a template to another template as I am trying to do above,
or is it not possible. Must I use specialisations, if I do how will I
know ever type that a user may put into my queue?

The problem is covered in the FAQ but it has nothing to do with passing
templates to templates (which is perfectly OK). The problem is that
template
code must always go in header files, take all the code from adsq.cpp and
put
it in adsq.h. See the FAQ
http://www.parashift.com/c++-faq-lite/containers-and-templates.html#faq-34.12
and following.

john

I wish to go on this subject. Given the 3 rules from the FAQ:
1.. A template is not a class or a function. A template is a "pattern"
that the compiler uses to generate a family of classes or functions.
2.. In order for the compiler to generate the code, it must see both the
template definition (not just declaration) and the specific types/whatever
used to "fill in" the template. For example, if you're trying to use a
Foo<int>, the compiler must see both the Foo template and the fact that
you're trying to make a specific Foo<int>.
3.. Your compiler probably doesn't remember the details of one .cpp file
while it is compiling another .cpp file. It could, but most do not and if
you are reading this FAQ, it almost definitely does not. BTW this is called
the "separate compilation model."
Suppose I wish to make a library using templates (being classes or
functions). Of course, I don't want my source code (i.e. my little secrets)
being distributed along with my binaries (.lib, .dll, or .so, name it!). On
the other hand, I cannot start specifying all possible instantiations, in my
..cpp, any potential user will try to make up.

Can someone tell me what are my options, as a Foo provider, to sell my
product to the Bar implementers?

Thank you.
 
V

Victor Bazarov

Maitre Bart said:
[...]
I wish to go on this subject. Given the 3 rules from the FAQ:
1.. A template is not a class or a function. A template is a "pattern"
that the compiler uses to generate a family of classes or functions.
2.. In order for the compiler to generate the code, it must see both the
template definition (not just declaration) and the specific types/whatever
used to "fill in" the template. For example, if you're trying to use a
Foo<int>, the compiler must see both the Foo template and the fact that
you're trying to make a specific Foo<int>.
3.. Your compiler probably doesn't remember the details of one .cpp file
while it is compiling another .cpp file. It could, but most do not and if
you are reading this FAQ, it almost definitely does not. BTW this is
called the "separate compilation model."
Suppose I wish to make a library using templates (being classes or
functions). Of course, I don't want my source code (i.e. my little
secrets) being distributed along with my binaries (.lib, .dll, or .so,
name it!). On the other hand, I cannot start specifying all possible
instantiations, in my .cpp, any potential user will try to make up.

You can't? Why can't you? Do you really have such a library that all
types could be used to instantiate templates?
Can someone tell me what are my options, as a Foo provider, to sell my
product to the Bar implementers?

You have three options.

One (just like many, if not all, other template code vendors do) is to
obfuscate the hell out of your code and still supply it all in the
headers you provide along with the rest of it. That's the most common
way. If you really want to protect your "secrets", get a patent. If
they are not patentable, they are not really secrets, are they?

Two is to limit your clients to use of a compiler that implements "export"
and make sure that all your object code (and template code) supplied is
compiled with that compiler.

Three is to limit your clients to instantiating your templates with
a short predetermined list of types. You library code has to contain the
necessary _explicit_specialisations_ of all the templates.

Both two and three are the ways to put yourself at a huge disadvantage
as far as software market goes. Since you said that you cannot rely on
option "three", then you are stuck with one or two, and limiting your
clients to a particular (potentially not very popular or even known)
compiler is in no way a good idea. Of course, the final decision is for
you to make.

Oh, the fourth option is to drop templates altogether and go with the
plain ol' set of functions and classes. Nothing essentially wrong with
that either. Majority of libraries on the market are still template-free.

Victor
 
M

Maitre Bart

Victor Bazarov said:
Maitre Bart said:
[...]
Suppose I wish to make a library using templates (being classes or
functions). Of course, I don't want my source code (i.e. my little
secrets) being distributed along with my binaries (.lib, .dll, or .so,
name it!). On the other hand, I cannot start specifying all possible
instantiations, in my .cpp, any potential user will try to make up.

You can't? Why can't you? Do you really have such a library that all
types could be used to instantiate templates?

Well, here is a simple case. Let's say that some of my template functions,
for example, contain a functor (or a predicate) a user has to provide as an
argument:

template <class _A_ , class _R_, class _Op_>
_R_ DoSomething(_A_ a_from, _A_ a_to, _Op_ a_converter);

How can I possibly think about all of the possible instantiations that may
exist in the whole world for 'a_converter'?
You have three options.

One (just like many, if not all, other template code vendors do) is to
obfuscate the hell out of your code and still supply it all in the
headers you provide along with the rest of it. That's the most common
way. If you really want to protect your "secrets", get a patent. If
they are not patentable, they are not really secrets, are they?

That is what I can observe in MS' STL implemention. Still, I wouldn't take
is solution if all my invested $$$ in development could be
reverse-engineered in a couple of hours. Would you? !!!
Two is to limit your clients to use of a compiler that implements "export"
and make sure that all your object code (and template code) supplied is
compiled with that compiler.

Then, I will need to read from Herb Sutter about 'export'.
Three is to limit your clients to instantiating your templates with
a short predetermined list of types. You library code has to contain the
necessary _explicit_specialisations_ of all the templates.

That is precisely my point!
Both two and three are the ways to put yourself at a huge disadvantage
as far as software market goes. Since you said that you cannot rely on
option "three", then you are stuck with one or two, and limiting your
clients to a particular (potentially not very popular or even known)
compiler is in no way a good idea. Of course, the final decision is for
you to make.

I think I will conclue rapidely on the subject (see below)...
Oh, the fourth option is to drop templates altogether and go with the
plain ol' set of functions and classes. Nothing essentially wrong with
that either. Majority of libraries on the market are still template-free.

Finaly, it all looks like that templates were not designed for "private"
libraries, unless they contain no secret and can be explicitely instantiated
for the basic types, which by nature is a "public" library.

Thanks for your opinion.
 

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,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top