template instantiation

Started by
9 comments, last by joanusdmentia 21 years, 5 months ago
I was wondering if anyone out there knows of a way to get templates to get instantiated for only a select group of types. That's probably not the best description, so here's an example. I've been implementing a temporary-free templated vector class (anyone who reads flipcode as well will recognize it from this tutorial: http://www.flipcode.com/tutorials/tut_fastmath.shtml). Anyway, say I have an operator overloaded as follows:

template < class TL, class TR >
inline const Expr2 < const TL, const TR, Add >
operator+(const TL &L, const TR &R)
{
	return Expr2 < const TL, const TR, Add >(L,R);			
}
 
is there any way to tell the compiler that we only want this operator instantiated only for certain types of TL and TR? At the moment it's got obvious problems being instantiated for any + operation, but if there isn't a way to do this i'm looking at 16 different copies of exactly the same code, per operator, with the only difference being the types of TL and TR Joanus D'Mentia --------------- The three phases of me... The twit, the tool and the lonely fool [edited by - joanusdmentia on November 1, 2002 9:04:07 PM] [edited by - joanusdmentia on November 1, 2002 9:05:10 PM]
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
Advertisement
What types do you want it to not work with?
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
The shorter answer would be what types I _do_ want it to work with. I only want it to work with scalars (e.g. float), Vector::Base (which as the name implies is a base class for all vectors) and Vector::Expr? (where ? = 1 or 2, these are classes that represent an expression).

When I first implemented it I didn''t even think about what affect it would have with other types, and my test environment really only did vector math so I didn''t run into any problems. When I moved it into my project though I got all sorts of errors, mostly stemming from stl iterators that were using the vectors overloaded operators.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
....echo.....echo....echo......

anybody?
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
If you are overriding the global + operator, I do not think there is a way to stop all types from being overridden the way you have it described.

However, putting the + operator within the vector class will do what you want, it will still be called when the vector class is used, but not for anything else.

So, for example:

  class Vector { inline Vector operator+(const Vector &value) const {  Vector tmp;  tmp.x = x + value.x; // etc...  return tmp; }};  
I''m writing this vector code as well, with ET and loop unrolling...
well, I''m going to be using this other guys code, but add loop unrolling, concept checks, etc, etc and then incorprate that in to libGDN.
but back to the question.
yes, you would put it into the vector class. that way only vectors use the + operator.

also. look into Boost concept checks for this kind of template metaprogramming. you can force compile time errors if the user attempts to instanitate vector classes with types that don''t support what you need, ie, +, -, *, copyable..


-----------------------------
Gamedev for learning.
libGDN for putting it all together.
ok, but the problem with that is it would no longer apply to the Expr? classes, so you wouldn''t be able to do something like this:

v4 = v1+v2+v3;

v1+v2 would evaluate to an Expr2 class, and you''d then need a seperate Expr2::operator+. Is there no way around this or am I just being really simple and looking over something?
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
just had an idea,

i could use a wrapper class that contains all of the operations like this:

template < class T >class Wrapper : public T{    ... operations ...};[\code]    
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
edit:
once again, a non-working 'solution'. When you're overloading operator+(), this scheme won't work. It just assures that some template function can be called with only certain parameters.

/* //I commented this away
This works (kinda variation of BOOST_STATIC_ASSERT):

    template <typename T> struct PLUS_OK_TYPE;template <> struct PLUS_OK_TYPE<float>{};template <> struct PLUS_OK_TYPE<double>{}; template <typename TL, typename TR>TL plus(TL a, TR b) {  sizeof(PLUS_OK_TYPE<TL>);  sizeof(PLUS_OK_TYPE<TR>);  return a + b;}  

Now if you call plus(), and the arguments don't have a specialization of PLUS_OK_TYPE, the linker will complain. I take a sizeof() because it'll be optimized away.

But it looks dirty...
*/

[edited by - civguy on November 2, 2002 8:37:10 AM]
KEWL!!!

that is EXACTLY what I was after!! I can't see why you're operator+ wouldn't have worked though, after trying your approach it worked fine. i think you would have run into trouble because you were using built-in types. If I do something like


  struct Test1 { int a,b; };struct Test2 { int a,b; };struct Test3 { int a,b; };template<class T> struct Test_ValidParam;template<> struct Test_ValidParam<Test1>{};template<> struct Test_ValidParam<Test2>{};template<class TL, class TR>int operator+(const TL &L, const TR &R){    sizeof(Test_ValidParam<TL>);    sizeof(Test_ValidParam<tr>);    return L.a + R.b;}void func(void){    Test1 t1;    Test2 t2;    Test3 t3;    int a = t1+t2;    // OK    int b = t1+t3;    // undefined type Test_ValidParam<Test3>}   


Thanks! My wrapper class did work, but the problem was I couldn't have scalars on the left hand side. Not a big deal, i know....


[edited by - joanusdmentia on November 2, 2002 8:56:27 PM]
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V

This topic is closed to new replies.

Advertisement