Templates - Create a method when T is a particular type?

C

cpisztest

Is it possible?

template<class T>
class MyTemplate
{
public:
MyTemplate();
~MyTemplate();
}

Now when T is type int, I want to have MyTemplate::Foo(), but if T is not type int, I do not want that method to exist.
 
C

cpisztest

Here is a better attempt. You can see where I am having problems in the comments. Do I need to duplicate both the interface and the implementation parts? and what is the syntax for the specialized method implementations?

I tried every permutation I could think of and can't get it.

//------------------------------------------------
class A
{
};

//------------------------------------------------
//------------------------------------------------
class B
{
};

//------------------------------------------------
//------------------------------------------------
template<class T>
class MyTemplateClass
{
public:

MyTemplateClass();
~MyTemplateClass();

void Foo(const T & arg);
};

//------------------------------------------------
template<class T>
MyTemplateClass<T>::MyTemplateClass()
{
}

//------------------------------------------------
template<class T>
MyTemplateClass<T>::~MyTemplateClass()
{
}

//------------------------------------------------
template<class T>
void MyTemplateClass<T>::Foo(const T & arg)
{
}

//------------------------------------------------
//------------------------------------------------
// Specialization
// So I have to redo the entire interface a second time even though I am
// only adding one new method?
template<>
class MyTemplateClass<class B>
{
public:

MyTemplateClass();
~MyTemplateClass();

void Foo(const B & arg);
void Bar(const B & arg);
};
/*
//------------------------------------------------
//------------------------------------------------
// I also must do the implementation of every method even though they
// are all the same, except for adding one new one?
// and what is the syntax?
template<>
MyTemplateClass<class B>::MyTemplateClass()
{
}

//------------------------------------------------
template<class T>
MyTemplateClass<double>::~MyTemplateClass()
{
}

//------------------------------------------------
template<class T>
void MyTemplateClass<T>::Foo(const T & arg)
{
}

//------------------------------------------------
template<>
void MyTemplateClass<B>::Bar(const B & arg)
{
}
*/
//------------------------------------------------
int main()
{
A argTypeA;
B argTypeB;

MyTemplateClass<A> templateTypeA;
MyTemplateClass<B> templateTypeB;

templateTypeA.Foo(argTypeA);
templateTypeB.Foo(argTypeB);

return 0;
}
 
L

Luca Risolia

template<class T>
class MyTemplate
{
public:
MyTemplate();
~MyTemplate();
}

Now when T is type int, I want to have MyTemplate::Foo(), but if T is not
type int, I do not want that method to exist.

If you meant "I do not want that method to be instantiated":

#include <type_traits>

template<class T>
class MyTemplate
{
public:
void Foo() {
static_assert(std::is_same<T, int>::value, "T is not int");
}
MyTemplate();
~MyTemplate();
};
 
C

cpisztest

So, when I do template specialization, I have to type out the entire template and its implementation for each specialization?

I'm going to have 9000 line header files....
 
C

cpisztest

Here is a better attempt. You can see where I am having problems in the comments. Do I need to duplicate both the interface and the implementation parts? and what is the syntax for the specialized method implementations?



I tried every permutation I could think of and can't get it.



//------------------------------------------------

class A

{

};



//------------------------------------------------

//------------------------------------------------

class B

{

};



//------------------------------------------------

//------------------------------------------------

template<class T>

class MyTemplateClass

{

public:



MyTemplateClass();

~MyTemplateClass();



void Foo(const T & arg);

};



//------------------------------------------------

template<class T>

MyTemplateClass<T>::MyTemplateClass()

{

}



//------------------------------------------------

template<class T>

MyTemplateClass<T>::~MyTemplateClass()

{

}



//------------------------------------------------

template<class T>

void MyTemplateClass<T>::Foo(const T & arg)

{

}



//------------------------------------------------

//------------------------------------------------

// Specialization

// So I have to redo the entire interface a second time even though I am

// only adding one new method?

template<>

class MyTemplateClass<class B>

{

public:



MyTemplateClass();

~MyTemplateClass();



void Foo(const B & arg);

void Bar(const B & arg);

};

/*

//------------------------------------------------

//------------------------------------------------

// I also must do the implementation of every method even though they

// are all the same, except for adding one new one?

// and what is the syntax?

template<>

MyTemplateClass<class B>::MyTemplateClass()

{

}



//------------------------------------------------

template<class T>

MyTemplateClass<double>::~MyTemplateClass()

{

}



//------------------------------------------------

template<class T>

void MyTemplateClass<T>::Foo(const T & arg)

{

}



//------------------------------------------------

template<>

void MyTemplateClass<B>::Bar(const B & arg)

{

}

*/

//------------------------------------------------

int main()

{

A argTypeA;

B argTypeB;



MyTemplateClass<A> templateTypeA;

MyTemplateClass<B> templateTypeB;



templateTypeA.Foo(argTypeA);

templateTypeB.Foo(argTypeB);



return 0;

}

I am still lost on the syntax. This will not compile. Please help with the implementation part.
 
W

Wouter van Ooijen

(e-mail address removed) schreef op 14-Apr-14 5:54 PM:
So, when I do template specialization, I have to type out the entire template and its implementation for each specialization?

I'm going to have 9000 line header files....

Why would you need so much different specializations?

If there is comonality in the specilizations my might be able to factor
it out.

If all else fails you can write a program that generates the header.

Wouter van Ooijen
 
V

Victor Bazarov

the comments. Do I need to duplicate both the interface and the
implementation parts? and what is the syntax for the specialized method
implementations?
I am still lost on the syntax. This will not compile. Please help with the implementation part.

I took the code from the message to which you replied, and it did
compile OK for me.

Can you please post both the shortest version of the code that gives the
error *and* the error (please also mark the line to which it refers
using some kind of comment, don't post all line numbers with the code),
like this:

// boo.cpp
...
class Boo {
Boo(B00&); // line 536
};

error (boo.cpp: 536) : 'B00' undefined

V
 
C

cpisztest

the comments. Do I need to duplicate both the interface and the

implementation parts? and what is the syntax for the specialized method

implementations?




I took the code from the message to which you replied, and it did

compile OK for me.



Can you please post both the shortest version of the code that gives the

error *and* the error (please also mark the line to which it refers

using some kind of comment, don't post all line numbers with the code),

like this:



// boo.cpp

...

class Boo {

Boo(B00&); // line 536

};



error (boo.cpp: 536) : 'B00' undefined



V



I am simply asking what the syntax is when implementing the methods belonging to the specialized template, outside of the specialized template. I already posted the code, the erroneous part was commented out with /* and */ with // what is the syntax here?

Here it is again without the erroneous part commented out:

//------------------------------------------------
class A
{
};

//------------------------------------------------
//------------------------------------------------
class B
{
};

//------------------------------------------------
//------------------------------------------------
template<class T>
class MyTemplateClass
{
public:

MyTemplateClass();
~MyTemplateClass();

void Foo(const T & arg);
};

//------------------------------------------------
template<class T>
MyTemplateClass<T>::MyTemplateClass()
{
}

//------------------------------------------------
template<class T>
MyTemplateClass<T>::~MyTemplateClass()
{
}

//------------------------------------------------
template<class T>
void MyTemplateClass<T>::Foo(const T & arg)
{
}

//------------------------------------------------
//------------------------------------------------
// Specialization
// So I have to redo the entire interface a second time even though I am
// only adding one new method?
template<>
class MyTemplateClass<class B>
{
public:

MyTemplateClass();
~MyTemplateClass();

void Foo(const B & arg);
void Bar(const B & arg);
};

//------------------------------------------------
//------------------------------------------------
// I also must do the implementation of every method even though they
// are all the same, except for adding one new one?
// and what is the syntax?
template<>
MyTemplateClass<class B>::MyTemplateClass()
{
}

//------------------------------------------------
template<class T>
MyTemplateClass<double>::~MyTemplateClass()
{
}

//------------------------------------------------
template<class T>
void MyTemplateClass<T>::Foo(const T & arg)
{
}

//------------------------------------------------
template<>
void MyTemplateClass<B>::Bar(const B & arg)
{
}

//------------------------------------------------
int main()
{
A argTypeA;
B argTypeB;

MyTemplateClass<A> templateTypeA;
MyTemplateClass<B> templateTypeB;

templateTypeA.Foo(argTypeA);
templateTypeB.Foo(argTypeB);

return 0;
}
 
V

Victor Bazarov

I am simply asking what the syntax is when implementing the methods
belonging to the specialized template, outside of the specialized
template. I already posted the code, the erroneous part was commented
out with /* and */ with // what is the syntax here?

I got it now. See below.
Here it is again without the erroneous part commented out:

//------------------------------------------------
class A
{
};

//------------------------------------------------
//------------------------------------------------
class B
{
};

//------------------------------------------------
//------------------------------------------------
template<class T>
class MyTemplateClass
{
public:

MyTemplateClass();
~MyTemplateClass();

void Foo(const T & arg);
};

All is fine so far.
//------------------------------------------------
template<class T>
MyTemplateClass<T>::MyTemplateClass()
{
}

//------------------------------------------------
template<class T>
MyTemplateClass<T>::~MyTemplateClass()
{
}

//------------------------------------------------
template<class T>
void MyTemplateClass<T>::Foo(const T & arg)
{
}

All is fine, still.
//------------------------------------------------
//------------------------------------------------
// Specialization
// So I have to redo the entire interface a second time even though I am
// only adding one new method?
template<>
class MyTemplateClass<class B>
{
public:

MyTemplateClass();
~MyTemplateClass();

void Foo(const B & arg);
void Bar(const B & arg);

So, the template specialization add a member. Totally OK.
};

//------------------------------------------------
//------------------------------------------------
// I also must do the implementation of every method even though they
// are all the same, except for adding one new one?
// and what is the syntax?
template<>
MyTemplateClass<class B>::MyTemplateClass()
{
}

//------------------------------------------------
template<class T>

Drop the 'template' here. What you're defining here is *not* a
template. It's a member of a fully specialized template, which is
actually a class. So, a member of a class is just a function, not a
template.
MyTemplateClass<double>::~MyTemplateClass()
{
}

So this needs to simply be

MyTempalateClass said:
//------------------------------------------------
template<class T>
void MyTemplateClass<T>::Foo(const T & arg)
{
}

This is a duplicate definition of that member. Remove it.
//------------------------------------------------
template<>
void MyTemplateClass<B>::Bar(const B & arg)
{
}

Again, since you're defining a regular member function of a full
template specialization (which is in itself a class and not a template),
there is no need to prepend it with 'template<..>', just write

void MyTemplateClass said:
//------------------------------------------------
int main()
{
A argTypeA;
B argTypeB;

MyTemplateClass<A> templateTypeA;
MyTemplateClass<B> templateTypeB;

templateTypeA.Foo(argTypeA);
templateTypeB.Foo(argTypeB);

return 0;
}

V
 
C

cpisztest

On 4/14/2014 2:37 PM, (e-mail address removed) wrote:

SNIP

Drop the 'template' here. What you're defining here is *not* a
template. It's a member of a fully specialized template, which is
actually a class. So, a member of a class is just a function, not a
template.

SNIP

So this needs to simply be

MyTempalateClass<double>::~MyTemplateClass() {}

SNIP

Excellent! All is right in the world again for today. Thanks Victor.
 

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

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top