|
-
January 17th, 2006, 04:46 PM
#1
Class template operator instantiation
Hi!
I'm using the following
Code:
class MyOut {
template<typename T> operator<<(T value);
}
Now I need to instantiate some implementations but
Code:
template operator<< <int>(int value);
gives a compiler error.
So, how can I instantiate class template operators?
Last edited by LSimao; January 17th, 2006 at 04:49 PM.
Reason: Correction
-
January 17th, 2006, 04:57 PM
#2
Re: Class template operator instantiation
Should we guess what is the error message?
-
January 17th, 2006, 05:07 PM
#3
Re: Class template operator instantiation
No, you shouldn't...
Code:
class MyOut {
template<typename T> MyOut& operator<<(T value);
template MyOut& operator<< <int>(int value);
}
Returns this beautifull list:
error C2143: syntax error : missing ';' before '<'
error C2530: '<<' : references must be initialized
error C2059: syntax error : '<'
error C2238: unexpected token(s) preceding ';'
The question is: syntax is not correct!!! What's the correct syntax or how can I instantiate such operators?
-
January 17th, 2006, 05:25 PM
#4
Re: Class template operator instantiation
Like this:
Code:
template <typename T>
class MyOut {
MyOut& operator<<(T value);
};
template <typename T>
MyOut<T>& MyOut<T>::operator<<(T value)
{
// ...
}
-
January 17th, 2006, 05:33 PM
#5
Re: Class template operator instantiation
That's not my target!!!
With your example I could have a MyOut for every kind of type, which acepts THAT kind of object in operator<<.
What I want is a single MyOut which acepts any kind of object in operator<<.
No multiple classes, but multiple operators.
I found one solution in C++ FAQs to solve my problem in but I still don't know how to instantiate class template operators.
-
January 18th, 2006, 01:47 AM
#6
Re: Class template operator instantiation
 Originally Posted by LSimao
No multiple classes, but multiple operators.
For that you will need to provide a template type parameter for the operator and not the class as a whole. Something like this:
Code:
class MyOut
{
public:
template<typename T>
MyOut& operator<< (T t);
};
template<typename T>
MyOut& MyOut::operator<< (T t)
{
//your code
//return a non-local MyOut
}
...or if MyOut is to be a class template as well, then something like this:
Code:
template<typename T>
class MyOut
{
public:
template<typename U>
MyOut<T>& operator<< (U u);
};
template<typename T>
template<typename U>
MyOut<T>& MyOut<T>::operator<< (U u)
{
//your code
//return a non-local MyOut
}
I hope one of these is what you wanted or else you would need to elaborate a bit more on your problem. Regards.
Can you help me with my homework assignment?, Before you post!, Use code tags, How to post!, Codeguru technical FAQs, C++ FAQ Lite, Stroustrup: C++ Style and Technique FAQ, Guru of the Week, Comeau C and C++ FAQs, Comeau C++ Templates FAQs, CUJ @ DDJ, Spam threshold
My Blogs : Learning C++ is fun | Abnegator's reflections
Open Threads : C++ Aha! Moments | Nature of work in C++?
-
January 18th, 2006, 05:29 AM
#7
Re: Class template operator instantiation
I'm struggling to figure out what you think you will achieve doing this. The only reason for having a template member is to write some generic code, and I don't see how an output operator can be generic. There's nothing to be gained by declaring a template and then explicitly specifying it for every type you can think of (apart from traits classes, but that's a different subject). You might as well just write overloads.
I, personally, find it useful to look at the way the standary library is structured if I'm contemplating doing something similar to some of its functionality. In this case, the standard's output streams don't define a template operator<<, they define specific overloads for the basic types and then leave the programmer to provide non-member implementations of operator<< for their own types. This is simple, extensible, and doesn't involve complex template techniques that some compilers (still) are not able to handle.
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
January 18th, 2006, 06:04 AM
#8
Re: Class template operator instantiation
I think the poster is asking how to specialise a template function.
That would be done like this:
Code:
class MyOut
{
public:
template < typename T > MyOut & operator<<( const T & );
// template specialisation for int.
template <> MyOut& operator<<( const int & i ); // or int i
};
The general case (not specialised) must be implemented in the header or you'll get linking errors. The specialised case can be implemented in MyOut.cpp.
-
January 18th, 2006, 07:39 AM
#9
Re: Class template operator instantiation
Oh, yeah, I see that. What I can't figure out is what he/she is expecting this code to do - what problem is it solving?
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell
-
January 18th, 2006, 11:33 AM
#10
Re: Class template operator instantiation
I'm getting I little frustrated!!!
Graham: I have actually implemented my function with inline operator, which solves linking problem. But inserting code in header files is not the correct way.
NMTop40: What you are talking about is specialization, not instantiation. I don't wan't to rewrite my code for each data type! I want my object/library file to contain template code for some kind of data types, just declaring them. That's instantiation. You cam see explicit intantiation in MSDN (http://msdn2.microsoft.com/en-us/lib...US,VS.80).aspx).
Now I'll try to show you my code and tell you what I want:
Code:
//report.h file:
class ReportOutput {
private:
iostream*file;
public:
template<typename T> ReportOutput& operator<<(T v);
};
//report.cpp file
template<typename T> ReportOutput& ReportOut::operator<<(T v) {
if (file) *file<<v;
cout<<v;
}
Using other modules to call operator<< will cause a linkage error because templates are not code, so report.obj will not contain any implementation of operator<< (see https://forums.codeguru.com/showthread.php?t=250284).
So I need to force the compiler to create some code and put it in object file for some kind of types. That's instantiation. For generic functions we could do:
Code:
//Header file:
template<typename T> void f(T); //Generic declaration
template void f<int>(int); //Instantiation for int
template void f<double>(double); //Instantiation for double
//Code file:
template<typename T> void f(T t) {
//Do somethig with t...
}
That would work when called from other modules for int and double types, because object file will contain code for f(int) and f(double). I hadn't to rewrite code for each type, just declare the instantiation. But for member operators, I don't know how to instantiate them, or what is the syntax for doing that.
A even better solution would be using "export" keyword, has refered in https://forums.codeguru.com/showthread.php?t=250284 but, as also refered there, my compiler does not support it!
Hope this can put this thread in the correct way!
Thanks you all!
Last edited by LSimao; January 18th, 2006 at 11:46 AM.
Reason: Review
-
January 18th, 2006, 02:52 PM
#11
Re: Class template operator instantiation
Okay, I will take one last try, Is this what you are looking for?
Code:
#include<iostream>
#include<fstream>
class ReportOutput {
private:
std::fstream* file;
public:
template<typename T>
ReportOutput& operator<<(T t);
template<typename T>
friend void operator<<(std::ostream& os, T v);
};
template<typename T>
ReportOutput& ReportOutput::operator<<(T t){
if(file)
*file << t;
std::cout << t;
}
template<typename T>
void operator<<(std::ostream& os, T v) {
os << v;
}
template void operator<<(std::ostream& , int);
template ReportOutput& ReportOutput::operator<<(int t);
template ReportOutput& ReportOutput::operator<<(double t);
int main(){
//some code
return 0;
}
The operator<< must generally be a friend member as shown in my code above and the first argument should be osteam&. But, I have provided the codes for your wierd overloads. The code compiles fine on Comeau. VC++ 6.0 fails to do so and hence couldnt test the different file scenario but keeping the explicit instantiation part in an implementation file might work well. Hope this helps. Regards.
Can you help me with my homework assignment?, Before you post!, Use code tags, How to post!, Codeguru technical FAQs, C++ FAQ Lite, Stroustrup: C++ Style and Technique FAQ, Guru of the Week, Comeau C and C++ FAQs, Comeau C++ Templates FAQs, CUJ @ DDJ, Spam threshold
My Blogs : Learning C++ is fun | Abnegator's reflections
Open Threads : C++ Aha! Moments | Nature of work in C++?
-
January 18th, 2006, 03:31 PM
#12
Re: Class template operator instantiation
No, that's no solution. You are overloading, not instantiating. (And I have no problem with ostream, it was just an example.)
One can explicitaly instantiate functions and classes but not, or I don't know how, operators! If you don't really know what is instantiation, please see http://msdn2.microsoft.com/en-us/lib...US,VS.80).aspx and https://forums.codeguru.com/showthread.php?t=250284.
While I was trying to test some code to show you my ideia, I get a "fatal error C1001: INTERNAL COMPILER ERROR", with VC++ 6.0. Maybe this compiler has several limitations on templates, like "extern". Maybe what I want is not possible...
On other words, I quit (at least by now)!
There are another solutions. Not so styliests. But working...
Thank you all, again!
-
January 18th, 2006, 03:37 PM
#13
Re: Class template operator instantiation
Maybe I'm missing something, but I don't think you can define template operators. When you define a template function like this
Code:
template<class T> void f(T arg);
then the actual names of instantiations of the template are f<char>, f<int>, f<double> and so forth. If you defined a template operator like this:
Code:
template<class T> ostream& operator<<(ostream&, const T&);
then the actual names of instantiations of the template would be operator<<<int>, operator<<<char>, operator<<<double> and so forth. However, for a function name to be recognized as an overload of the left insertion operator, it must have the exact name operator<<, be it in global scope or member scope of some class. So an instantiation of this template would never be recognized as an overload of operator<<.
Last edited by googler; January 18th, 2006 at 03:41 PM.
-
January 18th, 2006, 03:44 PM
#14
Re: Class template operator instantiation
Googler!!! You get the point!!! Thanks!!!
I can define them, but I can't instantiate them (or again, I don't know how - and nobody told me that it is impossible)!
Actually I'm using inline template operators like this:
Code:
class ReportOut {
public:
template<typename T> Reportout& operator<<(T t) {
cout<<t;
}
};
and it is working. Without writing more code, just that piece, for all datatypes (well, not all, but to all supported by cout<<).
What I was trying to achieve in this thread is a way to change inline code to source file instead of header file and instantiate them...
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
|