-
September 17th, 2015, 05:32 AM
#1
[RESOLVED] ambiguous behaviour of a class template with specialised function
I have got the following code in my header file:
Code:
template <class TType>
class CTestTmpl
{
public:
CTestTmpl() {};
~CTestTmpl() {};
void Get() const;
private:
};
template <class TType>
void
CTestTmpl<TType>::Get() const
{
std::cout << "This is not specialized: " << std::endl;
}
Then, I have the following specialised function:
Code:
template <>
void
CTestTmpl<int>::Get() const
{
std::cout << "This is a specialized implementation: " << std::endl;
}
If I put this specialised function in a ".cc" file, and then call it from some main function, like this:
Code:
int main()
{
CTestTmpl<int> intTmpl;
intTmpl.Get();
CTestTmpl<float> floatTmpl;
floatTmpl.Get();
}
it works as expected: The "intTmpl" uses the specialised function, and the "floatTmpl" uses the general function implementation. (The output is respectively: "This is a specialized implementation: " and "This is not specialized: ".)
However, if I put the CTestTmpl.o file in a lib, link to it from a different program, and execute the same code, both "intTmpl" and "floatTmpl" use the general function implementation. (The output is for both: "This is not specialized: ".)
On the other hand, if I put the specialised function in the header file, it will not compile in the "local code" (it complains the function is defined twice), but, when I compile only the class and put it in a lib, and link to it from the different program, now "intTmpl" correctly uses the specialised implementation and "floatTmpl" the general implementation. (With output respectively: "This is a specialized implementation: " and "This is not specialized: ".)
Could anybody explain to me what's going on here, please?
Where should I put the specialised function?
And, once I have specialised a function for one type (integer), do I have to specialise it for all types (float, double, ...)?
Best regards,
Machiel
-
September 17th, 2015, 06:01 AM
#2
Re: ambiguous behaviour of a class template with specialised function
Originally Posted by machielk
I have got the following code in my header file:
Code:
template <class TType>
class CTestTmpl
{
public:
CTestTmpl() {};
~CTestTmpl() {};
void Get() const;
private:
};
template <class TType>
void
CTestTmpl<TType>::Get() const
{
std::cout << "This is not specialized: " << std::endl;
}
Then, I have the following specialised function:
Code:
template <>
void
CTestTmpl<int>::Get() const
{
std::cout << "This is a specialized implementation: " << std::endl;
}
If I put this specialised function in a ".cc" file, and then call it from some main function, like this:
Code:
int main()
{
CTestTmpl<int> intTmpl;
intTmpl.Get();
CTestTmpl<float> floatTmpl;
floatTmpl.Get();
}
it works as expected: The "intTmpl" uses the specialised function, and the "floatTmpl" uses the general function implementation. (The output is respectively: "This is a specialized implementation: " and "This is not specialized: ".)
However, if I put the CTestTmpl.o file in a lib, link to it from a different program, and execute the same code, both "intTmpl" and "floatTmpl" use the general function implementation. (The output is for both: "This is not specialized: ".)
On the other hand, if I put the specialised function in the header file, it will not compile in the "local code" (it complains the function is defined twice), but, when I compile only the class and put it in a lib, and link to it from the different program, now "intTmpl" correctly uses the specialised implementation and "floatTmpl" the general implementation. (With output respectively: "This is a specialized implementation: " and "This is not specialized: ".)
Could anybody explain to me what's going on here, please?
Where should I put the specialised function?
And, once I have specialised a function for one type (integer), do I have to specialise it for all types (float, double, ...)?
Best regards,
Machiel
It sounds like you need to just forward declare your specialized implementation:
Code:
template <>
void
CTestTmpl<int>::Get() const;
Your compiler needs to *know* it exists to load it from lib (else it will just use its own default definition).
Regarding the "it complains the function is defined twice": It sounds like you might simply be missing include guards? If it complains about duplicate definition, this is a *compile* error: It happens before the linker, so at this point, there is no lib to care about. Only code.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
September 17th, 2015, 06:55 AM
#3
Re: ambiguous behaviour of a class template with specialised function
if you want a library (or a dll) to have a specific specialisation of a template availble to link to, then you need to explicitely instantiate the specialization. and make sure this instantiation is linkable.
-
September 17th, 2015, 07:04 AM
#4
Re: ambiguous behaviour of a class template with specialised function
Hi monarch_dodra and OReubens,
You are both right! I just implemented it the way you said and now it works perfectly.
Many thanks for your help!
-
September 17th, 2015, 07:34 AM
#5
Re: ambiguous behaviour of a class template with specialised function
Originally Posted by OReubens
and make sure this instantiation is linkable.
... and make sure that all its members can be instantiated as well ( for OP information, often templates are *not* designed to have all their members instantiated for a given type ... )
Originally Posted by machielk
You are both right! I just implemented it the way you said and now it works perfectly.
ok and all right, but for the future, keep in mind that the behaviour you observed in your OP is not guaranteed; IOW, whenever two translation units "see" different specializations of a template the result is generally undefined and no diagnostic is often required. So, the fact that something "works" does not mean it won't explode in the future ...
-
September 17th, 2015, 10:16 AM
#6
Re: [RESOLVED] ambiguous behaviour of a class template with specialised function
@superbonzo
Sorry, you lost me a bit there.
First of, what do you mean with "OP"?
What I do right now is the following:
In my header file I define my class template with all its member functions.
In the same header file, I give the implementation of all non-specialised methods plus (following monach and OReubens) the explicit instantiation of some specialised methods.
In the source file, I give the implementation of the same specialised methods.
With this, all member functions (specialised or not) should work correctly, right?
-
September 17th, 2015, 10:39 AM
#7
Re: [RESOLVED] ambiguous behaviour of a class template with specialised function
Originally Posted by machielk
@superbonzo
Sorry, you lost me a bit there.
First of, what do you mean with "OP"?
Original Post
-
September 18th, 2015, 01:55 AM
#8
Re: [RESOLVED] ambiguous behaviour of a class template with specialised function
Originally Posted by machielk
With this, all member functions (specialised or not) should work correctly, right?
yes, it's right.
I just wanted to warn you that given the code in your Original Post ( thank you STLDude ! ) :
Code:
// a.hpp
template <class T> struct A { void foo() { do_something(); } };
// b.cpp
#include <a.hpp>
int main( A<int> a; a.foo(); };
// c.cpp
#include <a.hpp>
template <>
void A<int>::foo() { do_something_else(); } };
the result is undefined and the compiler is not required to warn you in any way. That is, it may work as expected or not, it may give a compiler/linker error or not.
The moral of the story is that every cpp file must "see" the "same"(*) template definitions, or you 'll get in a lot of troubles, indipendently on whether the result appears to work or not.
((*) anyway, for your info, this does not mean that the include chain must be *exactly* the same ... but that's another story )
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|