Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Possible to check for specialisation?

1 view
Skip to first unread message

chris

unread,
Oct 5, 2004, 6:48:21 AM10/5/04
to
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

Michael Kurz

unread,
Oct 5, 2004, 3:13:42 PM10/5/04
to
*** post for FREE via your newsreader at post.newsfeed.com ***

Hi chris,

"chris" <ch...@bubblescope.net> schrieb im Newsbeitrag
news:cjtu5k$gt5$1...@pump1.york.ac.uk...

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>

-----= Posted via Newsfeed.Com, Uncensored Usenet News =-----
http://www.newsfeed.com - The #1 Newsgroup Service in the World!
-----== 100,000 Groups! - 19 Servers! - Unlimited Download! =-----

chris

unread,
Oct 6, 2004, 8:58:53 AM10/6/04
to
Michael Kurz wrote:
> *** post for FREE via your newsreader at post.newsfeed.com ***
>
> Hi chris,
>
> "chris" <ch...@bubblescope.net> schrieb im Newsbeitrag
> news:cjtu5k$gt5$1...@pump1.york.ac.uk...
>
>>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)
>
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

Michael Kurz

unread,
Oct 6, 2004, 10:02:01 AM10/6/04
to
Hi Chris,

"chris" <ch...@bubblescope.net> schrieb im Newsbeitrag

news:4163EC0D...@bubblescope.net...


> >
> 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>


0 new messages