Possible to check for specialisation?

C

chris

I am currently writing a templated function and want it to be able to
implement it differently based on if the input class has implemented an
overload of swap. However, I can't figure out how I can test for such a
condition, although it seems like a reasonably sensible thing to be able
to do..

Thank you,

Chris
 
M

Michael Kurz

Hi chris,

chris said:
I am currently writing a templated function and want it to be able to
implement it differently based on if the input class has implemented an
overload of swap. However, I can't figure out how I can test for such a
condition, although it seems like a reasonably sensible thing to be able
to do..

I would suggest that you inherit all classes, which can swap from a kind of
compile time interface class
CSwap. Then use a bit of lovely code from Loki (Andrei Alexandrescu),
"Loki::SuperSubclass<CSwap, T>::value". I can particularily recommend the
book
"modern C++ design" from Andrei Alexandrescu, where the background of the
code used within Loki is explained in detail.
Please see the snip of code below. (I tried it with VC7 13.10.3052)


Best Regards
Michael

<snip>
#include "TypeManip.h" // From Loki

// Compiletime interface class fro Swap.
class CSwap{
public:
void Swap();

};

// Swapable class (public interits from CSwap)
class A : public CSwap{
public:
void Test(){
printf("A::Test\n");
}

void Swap(){
printf("\nPerfrom swap...\n");
}
};

// Not swapable class.
class B{
public:
void Test(){
printf("B::Test\n");
}
};

// Template function which performs action an elements of a given type T.
template<class T>
void test(T& val){
// The template Loki::SuperSubclass<...> is the magic from Andrei
Alexandrescu's Loki
testImpl<T, Loki::SuperSubclass<CSwap, T>::value>::action(val);
}


// Use class template as partial specialization of function is not possible.
// Implementation with no swap.
template<class T, bool swap_on>
struct testImpl{
static void action(T& val){
printf("No swap");
}
};

// Implementation with swap. (specialize fro swap_on=true)
template<class T>
struct testImpl<T, true>{
static void action(T& val){
printf("swap");
val.Swap();
}
};




int main(int argc, char* argv[]){

printf("call test with class A (swapable)\n");
test(A());
printf("\n");
printf("call test with class B (NOT swapable)\n");
test(B());
}

</snip>
 
C

chris

Michael said:
Hi chris,




I would suggest that you inherit all classes, which can swap from a kind of
compile time interface class
CSwap. Then use a bit of lovely code from Loki (Andrei Alexandrescu),
"Loki::SuperSubclass<CSwap, T>::value". I can particularily recommend the
book
"modern C++ design" from Andrei Alexandrescu, where the background of the
code used within Loki is explained in detail.
Please see the snip of code below. (I tried it with VC7 13.10.3052)
While that is indeed a nice idea, is has the unfortunate disadvantage
that I can't use it with std::vector, list, etc... :\ However, this
might simply be the fate I have to face.

Thank you,

Chris
 
M

Michael Kurz

Hi Chris,

chris said:
While that is indeed a nice idea, is has the unfortunate disadvantage
that I can't use it with std::vector, list, etc... :\ However, this
might simply be the fate I have to face.


You are right of course.
But you extend my initial suggestion a bit:
-Instead of using Loki::SuperSubclass<..> directly you could wrap it within
a template
called something like "IsSwapable<T>", where the default implementation uses
the Loki code of course.

-For the templates of e.g std::xxx you provide specializations for
IsSwapable<T>

At the end you have 2 choices to make something swapable:
1. Inherit from CSwap
2. Provide a specialization of IsSwapable<T> for a specific type or
template type.


Regards
Michael

<snip>
//! Default implementation, where everything inherited from CSwap is
swapable.
template<class T>
struct IsSwapable{
enum{value = Loki::SuperSubclass<CSwap<T>, T>::value};
};

//! Specialize for all std::vectors true.
template<class T>
struct IsSwapable<std::vector<T> >{
enum{value = true};
};

// Template function which performs action an elements of a given type
T.
template<class T>
void test(T& val){
// Use IsSwapable instead of Loki::SuperSubclass<>.
testImpl<T, IsSwapable<T>::value>::action(val);
}
...
</snip>
 

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

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top