Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > How to do explicit specialization of non-type template function

Reply
Thread Tools

How to do explicit specialization of non-type template function

 
 
Bill
Guest
Posts: n/a
 
      02-19-2008
Hi,
I have a quetion how to specialization a non-type templat function, I
use VC++ 2005.

My code is:

#include "stdafx.h"

enum VariableType
{
enumASCII = 1,
enumDOUBLE = 2,
enumDURATION = 3,
enumINTEGER = 4
};

template< VariableType >
struct HrtTypes{
};

template< size_t _size >
struct INTEGERS
{
typedef signed char value_type;
typedef signed char* pointer;
typedef HrtTypes<enumINTEGER> TypeTrait;
enum { size = _size };
};

template<typename T>
bool foo(T*, typename T::TypeTrait*);

//specializaton for INTEGERS<1>,<2>, ...<n>
template<typename T>
bool foo(T*, HrtTypes<enumINTEGER>*)
{
return true;
}

int main()
{
INTEGERS<1>* p1;

foo(p1, INTEGERS<1>::TypeTrait*(0));

size_t n = 4;
INTEGERS<4> p2;

foo(p2, INTEGERS<4>::TypeTrait*(0));
}

I hope all INTEGERS<1>...type can use the specilization for template
function foo(....). I think the compiler could get that
HrtTypes<enumINTEGER> is same with INTEGERS<1>::TypeTrait, so foo(p1,
INTEGERS<1>::TypeTrait*(0)) and foo(p2, INTEGERS<4>::TypeTrait*(0));
can call the same function above.
but it seems these not works.

who can give me more comments
Thanks very well.

 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      02-19-2008
Bill wrote:
> I have a quetion how to specialization a non-type templat function, I
> use VC++ 2005.
>
> My code is:
>
> #include "stdafx.h"


That's not a standard header. You might be better off leaning the
language without the use of precompiled headers, BTW.

>
> enum VariableType
> {
> enumASCII = 1,
> enumDOUBLE = 2,
> enumDURATION = 3,
> enumINTEGER = 4
> };
>
> template< VariableType >
> struct HrtTypes{
> };
>
> template< size_t _size >
> struct INTEGERS
> {
> typedef signed char value_type;
> typedef signed char* pointer;
> typedef HrtTypes<enumINTEGER> TypeTrait;
> enum { size = _size };
> };
>
> template<typename T>
> bool foo(T*, typename T::TypeTrait*);
>
> //specializaton for INTEGERS<1>,<2>, ...<n>
> template<typename T>
> bool foo(T*, HrtTypes<enumINTEGER>*)
> {
> return true;
> }
> [..]


Sorry, you can't do that. You're trying to define a partial
specialisation of a function template, which is not allowed.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
 
 
 
Pete Becker
Guest
Posts: n/a
 
      02-19-2008
On 2008-02-19 11:10:13 -0500, "Victor Bazarov" <(E-Mail Removed)> said:

> Bill wrote:
>> I have a quetion how to specialization a non-type templat function, I
>> use VC++ 2005.
>>
>> My code is:
>>
>> #include "stdafx.h"

>
> That's not a standard header. You might be better off leaning the
> language without the use of precompiled headers, BTW.


And, especially, without Microsoft's sledge hammer notion of
precompiled headers.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

 
Reply With Quote
 
Marcel Müller
Guest
Posts: n/a
 
      02-19-2008
Victor Bazarov schrieb:
> Sorry, you can't do that. You're trying to define a partial
> specialisation of a function template, which is not allowed.


Usually a work-around is to use function object and define a partial
specialization of this class.


Marcel
 
Reply With Quote
 
Bill
Guest
Posts: n/a
 
      02-20-2008
Thanks for your answer,

1. Yes, you are right, I agree with remove the stdafx.h from header
file.
2. I am still not clear why I can't use particial specialization here,
doe's vc2005 not support it or the particial specialization not work
in this case?


 
Reply With Quote
 
Bill
Guest
Posts: n/a
 
      02-20-2008
On Feb 20, 1:01*am, Marcel Müller <(E-Mail Removed)>
wrote:
> Victor Bazarov schrieb:
>
> > Sorry, you can't do that. *You're trying to define a partial
> > specialisation of a function template, which is not allowed.

>
> Usually a work-around is to use function object and define a partial
> specialization of this class.
>
> Marcel


Thank you, could you send more details?
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      02-20-2008
On Feb 20, 2:45 am, Bill <(E-Mail Removed)> wrote:

[..]
> 2. I am still not clear why I can't use particial specialization here,
> doe's vc2005 not support it or the particial specialization not work
> in this case?


Because, as Victor said, there is no partial specialization of
function templates. It doesn't exist in the language. You can
overload function templates, or use partial specialization of a
class template.

In your particular case, in fact, it looks to me like you have
overloaded the function template, and not used partial
specialization. And after correcting the obvious typos in your
code (no parentheses around the type specification in the C
style cast, and a forgotten address-of operator in the second
function call), it compiles with g++. (You really should use
copy/paste when posting, to make sure that the code you post is
the code actually causing the problems.)

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
Marcel Müller
Guest
Posts: n/a
 
      02-22-2008
Bill wrote:
> On Feb 20, 1:01 am, Marcel Müller <(E-Mail Removed)>
> wrote:
>> Victor Bazarov schrieb:
>>
>>> Sorry, you can't do that. You're trying to define a partial
>>> specialisation of a function template, which is not allowed.

>> Usually a work-around is to use function object and define a partial
>> specialization of this class.
>>
>> Marcel

>
> Thank you, could you send more details?


Example:


/************************************************** ***************************
*
* cast traits class
*
************************************************** ***************************/

template <typename D, typename S>
struct my_cast_traits
{ static D do_static_cast(S s)
{ return static_cast<D>(s);
}
static D do_dynamic_cast(S s)
{ return dynamic_cast<D>(s);
}
static D do_const_cast(S s)
{ return const_cast<D>(s);
}
// we will never overload the reinterpret_cast!
};


/************************************************** ***************************
*
* template functions for convenience
*
************************************************** ***************************/

// wee need wrappers here
template <typename D, typename S>
inline D my_static_cast(S s)
{ return my_cast_traits<D,S>::do_static_cast(s);
}
template <typename D, typename S>
inline D my_dynamic_cast(S s)
{ return my_cast_traits<D,S>::do_dynamic_cast(s);
}
template <typename D, typename S>
inline D my_const_cast(S s)
{ return my_cast_traits<D,S>::do_const_cast(s);
}


/************************************************** ***************************
*
* Example for specialization for casting boost::shared_ptr
*
************************************************** ***************************/

template <typename D, typename S>
struct my_cast_traits<boost::shared_ptr<D>, boost::shared_ptr<S> >
{ static boost::shared_ptr<D> do_static_cast(boost::shared_ptr<S> s)
{ return boost::static_pointer_cast<D>(s);
}
static boost::shared_ptr<D> do_dynamic_cast(boost::shared_ptr<S> s)
{ return boost::dynamic_pointer_cast<D>(s);
}
static boost::shared_ptr<D> do_const_cast(boost::shared_ptr<S> s)
{ return boost::const_pointer_cast<D>(s);
}
};



Now my_static_cast behaves exactly as static cast (see note below),
except that you can additionally write

boost::shared_ptr<X> x;
boost::shared_ptr<Y> y = my_static_cast<boost::shared_ptr<Y>>(x);

This static cast is normally not allowed. And this is an important
difference to C style pointers.

Practically I partially specialized the template function
my_static_cast. Syntactically only a helper class is partially specialized.


Note: since C++ knows nothing about side effect free functions they
cannot be evaluated at compile time even if their arguments are compile
time constants. This results in the difference that the above cast
replacement removes the compile time constant attribute from any
argument passed to it. The built-in static_cast function does not do this.
In my opinion this is a principal lack in the C++ language.


Marcel
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
illegal explicit template specialization stain C++ 3 05-30-2006 08:08 AM
What's the difference betwwen explicit instantiaion and explicit specialization? Andy C++ 5 01-30-2005 11:46 PM
Explicit and partial template specialization nested in classes. Patrick Kowalzick C++ 0 10-29-2004 02:45 PM
Is explicit template qualification required for explicit delete? J.T. Conklin C++ 1 08-11-2004 02:06 AM



Advertisments