473,769 Members | 5,724 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Template problems

Hi,

I want to use a callback function together with
templates. Let's say I've this code:

File a.h:

class A
{
private:
template< typename T >
void func( bool( T::*f)(void) );
};
-----------------

File a.cc:

template< typename T >
void A::func( bool( T::*f)(void) )
{
f();
}
------------------

and another class B that uses "func":

File b.cc:
#include "a.h"

bool B::func2(void)
{
return true;
}

void B::func3()
{
A a;
a->func( &B::func2 );
}

During compilation I get the error
undefined reference to `void A::func<B>(bool (B::*)())'.

The problems seem to be that during compilation of class B, the
template function A::func is not completely known (just the
function declaration of the header file, but not the function
definition). I assume that one solution is to move the function
body of A::func into the header file a.h to make it visible during
compilation of class B.

However, this seems not to be the best solution because I must
reveal the implementation of A::func to anyone who wants to use
it. Without templates, I could compile class A into a library
and just provide the header file a.h together with the library.
So, the users would not see the implementation of class A.
However, when I move code from the source file into the header
file, I show my implementation which I would like to avoid.
Are there any solutions for that? Or are templates in general
crucial when source code must be kept closed?

Best regards,
Tim
Jun 27 '08 #1
8 1751
"Tim Frink" <pl*****@yahoo. dewrote in message

[snip]
During compilation I get the error
undefined reference to `void A::func<B>(bool (B::*)())'.

The problems seem to be that during compilation of class B, the
template function A::func is not completely known (just the
function declaration of the header file, but not the function
definition). I assume that one solution is to move the function
body of A::func into the header file a.h to make it visible during
compilation of class B.

However, this seems not to be the best solution because I must
reveal the implementation of A::func to anyone who wants to use
it. Without templates, I could compile class A into a library
and just provide the header file a.h together with the library.
So, the users would not see the implementation of class A.
However, when I move code from the source file into the header
file, I show my implementation which I would like to avoid.
Are there any solutions for that? Or are templates in general
crucial when source code must be kept closed?
Check this FAQ --
http://www.parashift.com/c++-faq-lit...html#faq-35.14

--
http://techytalk.googlepages.com
Jun 27 '08 #2
On May 7, 12:04*pm, Tim Frink <plfr...@yahoo. dewrote:
Hi,

I want to use a callback function together with
templates. Let's say I've this code:

File a.h:

class A
{
* *private:
* * *template< typename T >
* * *void func( bool( T::*f)(void) );};
[snips]

Do you really want that private? That seems wrong for a callback.

Also, do you really want it to be a template member function?
Or do you want the class to be a template class? That is, do
you want all the items, of various different types, that make
use of this callback to use the same class A? It would appear
you are trying to collect callbacks for more than one T in the
same instance. Is that really what you want?
Socks
Jun 27 '08 #3
Puppet_Sock wrote:
On May 7, 12:04 pm, Tim Frink <plfr...@yahoo. dewrote:
>Hi,

I want to use a callback function together with
templates. Let's say I've this code:

File a.h:

class A
{
private:
template< typename T >
void func( bool( T::*f)(void) );};
[snips]

Do you really want that private? That seems wrong for a callback.
Why? It would actually make sure that nobody except whoever gets
the pointer to that function, can call it. Not a bad idea for
a callback to be private.
Also, do you really want it to be a template member function?
Or do you want the class to be a template class? That is, do
you want all the items, of various different types, that make
use of this callback to use the same class A? It would appear
you are trying to collect callbacks for more than one T in the
same instance. Is that really what you want?
I wonder, why all those questions? Did it have anything to do
with the problem the OP experienced? Generally speaking, the
link error (this is what the OP's got, isn't it?) is because it
is a function template that is used in 'main' and its source is
not visible so that the compiler can generate the function. But
the design has really nothing to do with it, does it? Simply
tell the OP to place the definition in the header.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 27 '08 #4
I wonder, why all those questions? Did it have anything to do
with the problem the OP experienced? Generally speaking, the
link error (this is what the OP's got, isn't it?) is because it
is a function template that is used in 'main' and its source is
not visible so that the compiler can generate the function. But
the design has really nothing to do with it, does it? Simply
tell the OP to place the definition in the header.
That's my point. But when I place the definition into the header
which I want to make visible to other users as API to my library,
also the definition of A::func becomes visible to everyone. And
this is what I would like to avoid. This was the reason of my post
to ask you if there are any solution to not change the semantics
of my code example but still somehow keep the definition of A::func
hidden.

Regards,
Jun 27 '08 #5
Stephan Ceram wrote:
>I wonder, why all those questions? Did it have anything to do
with the problem the OP experienced? Generally speaking, the
link error (this is what the OP's got, isn't it?) is because it
is a function template that is used in 'main' and its source is
not visible so that the compiler can generate the function. But
the design has really nothing to do with it, does it? Simply
tell the OP to place the definition in the header.

That's my point. But when I place the definition into the header
which I want to make visible to other users as API to my library,
also the definition of A::func becomes visible to everyone. And
this is what I would like to avoid. This was the reason of my post
to ask you if there are any solution to not change the semantics
of my code example but still somehow keep the definition of A::func
hidden.
"How do I make it visible to the client's compiler but not to the
clients themselves?" Well, use a compiler that supports template
export and tell the clients to do the same. If you can, that is.
If you cannot, you're SOL.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 27 '08 #6
"Victor Bazarov" <v.********@com Acast.netwrote in news:fvspke$ddg $1
@news.datemas.d e:
Stephan Ceram wrote:
>>I wonder, why all those questions? Did it have anything to do
with the problem the OP experienced? Generally speaking, the
link error (this is what the OP's got, isn't it?) is because it
is a function template that is used in 'main' and its source is
not visible so that the compiler can generate the function. But
the design has really nothing to do with it, does it? Simply
tell the OP to place the definition in the header.

That's my point. But when I place the definition into the header
which I want to make visible to other users as API to my library,
also the definition of A::func becomes visible to everyone. And
this is what I would like to avoid. This was the reason of my post
to ask you if there are any solution to not change the semantics
of my code example but still somehow keep the definition of A::func
hidden.

"How do I make it visible to the client's compiler but not to the
clients themselves?" Well, use a compiler that supports template
export and tell the clients to do the same. If you can, that is.
If you cannot, you're SOL.

V
One other possibility (of limited scope) is to explicitly instantiate your
template with the common types you are likely to want and compile that into
a lib and only ship a forward declaration style template definition in your
header. That won't work if you are shipping a template that is supposed to
work with a user defined class though.

joe
Jun 27 '08 #7
Hi,
One other possibility (of limited scope) is to explicitly instantiate your
template with the common types you are likely to want and compile that into
a lib and only ship a forward declaration style template definition in your
header. That won't work if you are shipping a template that is supposed to
work with a user defined class though.
What you mean is probably the second suggested solution in
http://www.parashift.com/c++-faq-lit...html#faq-35.15
(add template class Foo<int>; in Foo.cpp), right?

This example is describing a template class, however I'm using
a template function

template< typename T >
void func( bool( T::*f)(void) );

Can this trick with the forward declaration be also applied to template
functions? If so, what do I have to insert in my example file a.cc?
template class A<B>; won't work.

This solution seems to be a sort of a hack because I must know in
advance what template types will be use for 'T'. Can I add different
forward declarations (obviously this must be adjusted to my template
functions) like
template class A<B>;
template class A<C>;

If so it is still better than using the concrete type of class
for "T".
Jun 27 '08 #8
Tim Frink <pl*****@yahoo. dewrote in
news:68******** *****@mid.indiv idual.net:
Hi,
>One other possibility (of limited scope) is to explicitly instantiate
your template with the common types you are likely to want and
compile that into a lib and only ship a forward declaration style
template definition in your header. That won't work if you are
shipping a template that is supposed to work with a user defined
class though.

What you mean is probably the second suggested solution in
http://www.parashift.com/c++-faq-lit...html#faq-35.15
(add template class Foo<int>; in Foo.cpp), right?

This example is describing a template class, however I'm using
a template function

template< typename T >
void func( bool( T::*f)(void) );

Can this trick with the forward declaration be also applied to
template functions? If so, what do I have to insert in my example file
a.cc? template class A<B>; won't work.
I believe so. The following seems to work for me (I make no guarantees
about it being what you want to do and things like include guards and
doing something useful is left as an exercise), however:

::: t-f.h ::: The public file

template<class T>
bool func(bool (T::*f)(), T * p);
class AlwaysFails
{
public:
bool f();
};

class AlwaysWorks
{
public:
bool f();
};
::: t1.cpp ::: The private implementation distributed as .o or .obj
#include "t-f.h"

bool AlwaysFails::f( )
{
return false;
}

bool AlwaysWorks::f( )
{
return true;
}

template<class Tbool func( bool (T::*f)(), T * p)
{
return (p->*f)();
}

template bool func( bool (AlwaysFails::* f)(), AlwaysFails * p);

template bool func( bool (AlwaysWorks::* f)(), AlwaysWorks * p);
::: t.cpp ::: The client app
#include <iostream>
#include <ostream>

#include "t-f.h"
int main()
{
AlwaysFails af;
AlwaysWorks aw;

std::cout << "AlwaysFail = " << func(&AlwaysFai ls::f, &af) <<
std::endl;

std::cout << "AlwaysWork = " << func(&AlwaysWor ks::f, &aw) <<
std::endl;

}
>
This solution seems to be a sort of a hack because I must know in
advance what template types will be use for 'T'. Can I add different
forward declarations (obviously this must be adjusted to my template
functions) like
template class A<B>;
template class A<C>;

If so it is still better than using the concrete type of class
for "T".
Yes, its definitely a work-around. You really want an idealized form of
export. Idealized in the sense that it couldn't be reverse engineered.
(Even with export, the source needs to be destributed, but it's in some
internal form, An ambitious soul could decompile it into the original
source, so its still a less than ideal solution, but compilers aren't
really into the security business so AFAIK the export files aren't that
hard to reverse).

HTH,
joe
Jun 27 '08 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
3624
by: Dave Rahardja | last post by:
OK, so I've gotten into a philosophical disagreement with my colleague at work. He is a proponent of the Template Method pattern, i.e.: class foo { public: void bar() { do_bar(); } protected: virtual void do_bar() {} };
11
3217
by: Guotao Luan | last post by:
Hello All: I notice that there have been frequent questions being asked about template here so I guess it is okay to post this message here. I just wrote a c++ tempalte tutorial/review, I would like to hear feedbacks from other users. I do not have much experience with template myself so I am sure there are many problems or even mistakes in this material. Comments of all types are welcomed. and I also hope this tutorial/review is helpful...
3
3939
by: Chris | last post by:
I am having a very strange problem involving virtual functions in template classes. First of all, here is an extremely simplified structure of the two classes I am having problems with. template<class Type> class base { public: base& operator/=(const base&); Type *image;
1
1209
by: Lewis Baker | last post by:
I am having some template problems in VC7.1 The following code should compile fine but I get the error: 'warning C4667: 'void F(Traits<T>::P)' : no function template defined that matches forced instantiation'
3
1338
by: Serge Skorokhodov (216716244) | last post by:
Hi, I just seeking advice. Some background information first because I've run into issues that seems pretty obscure to me:( Quick search through KB yields next to nothing. Simplified samples work OK as well, the problems appear in rather bulky code:( I'm trying to implement some signal processing algorithm using
12
1890
by: Jim Langston | last post by:
I have a template I call StrmConvert, which uses std::stringstream to convert from any type to any other type that can be used by stringstring. This is what it looks like: template<typename T, typename F > T StrmConvert( F from ) { std::stringstream temp; temp << from; T to = T(); temp >> to;
4
1828
by: Howard Gardner | last post by:
// I think that there is no way to write the template "cant_write_me" in // this example. Would love to be wrong. // one of many approaches that won't work template< template< typename class struct cant_write_me{}; template< template< typename, typename class struct cant_write_me{}; template< typename struct arity_one{}; template< typename, typename struct arity_two{};
7
3465
by: mathieu | last post by:
Hello, I did read the FAQ on template(*), since I could not find an answer to my current issue I am posting here. I have tried to summarize my issue in the following code (**). Basically I am trying to hide the `complexity` of template from the user interface. If you look at the code DataSet should be the object that my user manipulate. Unfortunately by doing so the object returned by DataSet::Get is a FloatingPt, so without the virtual...
45
2922
by: charles.lobo | last post by:
Hi, I have recently begun using templates in C++ and have found it to be quite useful. However, hearing stories of code bloat and assorted problems I decided to write a couple of small programs to check. What I expected was that there would be minor code bloat and some speed improvement when using templates. However... I wrote a basic list container (using templates), and a list container (using virtual derived classes). I also tried...
4
2580
by: AndrewD | last post by:
Hey C++ folks, I created this today, just for fun. You can make object allocation for any class around 6 times faster, simply by doing the following. class MyClass : public TXpQAlloc<MyClass,N> N is a chunking factor (defaults to 10).
0
10211
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10045
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9994
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9863
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8870
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6673
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5298
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5447
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3561
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.