C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

About templates

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Ema
Guest





PostPosted: Wed Feb 22, 2006 12:06 pm    Post subject: About templates Reply with quote



Hi, I'm looking for a writing technique that would allow me to specify
which kind of <typename T> one template function can accept: Eg:

In case i have :

template<typename T> inline void doSomething(const T& a, const T& b)
{
...
...
}

and if I'd like to have it defined just for 'double' and 'int', how
could i specify that on the upper declaration, avoiding to full
specialize 'doSomething' for every T i need to be specialized?

Does exist a command that can limit the different values that T can be?

Thanks in advance,
Ema.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Carl Barron
Guest





PostPosted: Thu Feb 23, 2006 1:06 am    Post subject: Re: About templates Reply with quote



In article <1140519259.598111.112100 (AT) g43g2000cwa (DOT) googlegroups.com>, Ema
<oriani.blue_reply (AT) bancaimi (DOT) it> wrote:

Quote:
Hi, I'm looking for a writing technique that would allow me to specify
which kind of <typename T> one template function can accept: Eg:

In case i have :

template<typename T> inline void doSomething(const T& a, const T& b)
{
...
...
}

and if I'd like to have it defined just for 'double' and 'int', how
could i specify that on the upper declaration, avoiding to full
specialize 'doSomething' for every T i need to be specialized?

Does exist a command that can limit the different values that T can be?

simply something like this:

template <typename T> struct tag{};
template <> struct tag<int> {typedef void type;};
template <> struct tag<double> {typedef void type;};

template <typename T> void doSomething(const T &a,const T &b,
tag<T>::type * = 0) { /* */}

comes to mind.
or using boost this becomes.
template <typename T>
inline void doSomething(const T &a,const T &b,
boost::enable_if
<
boost::mpl::contains
<
boost::mpl::vector<int,double>,
T
Quote:

::type * = 0)
{

/**/
}

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
dagecko
Guest





PostPosted: Thu Feb 23, 2006 1:06 am    Post subject: Re: About templates Reply with quote



Le Wed, 22 Feb 2006 06:06:09 -0500, Ema a écrit :

Quote:
Hi, I'm looking for a writing technique that would allow me to specify
which kind of <typename T> one template function can accept: Eg:

In case i have :

template<typename T> inline void doSomething(const T& a, const T& b)
{
...
...
}

and if I'd like to have it defined just for 'double' and 'int', how
could i specify that on the upper declaration, avoiding to full
specialize 'doSomething' for every T i need to be specialized?

Does exist a command that can limit the different values that T can be?

The best thing is not to use templates :)

void myfunc (double, double);
void myfunc (int, int);

But if you really want to use template, just declare the
template function without implementing it, and specialize
it for the types you want:

template <typename T>
void func (T t);

template <>
void func (double)
{
....
}

template <>
void func (int)
{
....
}


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
kwikius
Guest





PostPosted: Thu Feb 23, 2006 1:06 am    Post subject: Re: About templates Reply with quote

Ema wrote:
Quote:
Hi, I'm looking for a writing technique that would allow me to specify
which kind of <typename T> one template function can accept: Eg:

In case i have :

template<typename T> inline void doSomething(const T& a, const T& b)
{
...
...
}

and if I'd like to have it defined just for 'double' and 'int', how
could i specify that on the upper declaration, avoiding to full
specialize 'doSomething' for every T i need to be specialized?

Does exist a command that can limit the different values that T can be?

You can overload (functions are overloaded rather than specialized) the
function or use boost::enable_if which can help if you need to avoid
unwanted implicit conversions

/*
These headers are available as part of the boost distro
http://www.boost.org. They dont require any building BTW
*/
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/or.hpp>

template<typename T>
inline
typename boost::enable_if<
boost::mpl::or_<
boost::is_same<T,int>,
boost::is_same<T,double>
Quote:
,
void //required result_type

//void is default BTW
Quote:
::type
doSomething(const T& a, const T& b)

{}

int main()
{
doSomething(1.,1.);
doSomething(1,1);
doSomething(1U,1U); // Error
}

regards
Andy Little


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Thomas Maeder
Guest





PostPosted: Thu Feb 23, 2006 2:06 am    Post subject: Re: About templates Reply with quote

"Ema" <oriani.blue_reply (AT) bancaimi (DOT) it> writes:

Quote:
Hi, I'm looking for a writing technique that would allow me to
specify which kind of <typename T> one template function can accept:
Eg:

In case i have :

template<typename T> inline void doSomething(const T& a, const T& b)
{
...
...
}

and if I'd like to have it defined just for 'double' and 'int', how
could i specify that on the upper declaration, avoiding to full
specialize 'doSomething' for every T i need to be specialized?

Does exist a command that can limit the different values that T can
be?

You should be able to get what you are looking by combining the Boost
type_traits and static_assert libraries (cf. http://www.boost.org/).

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Victor Bazarov
Guest





PostPosted: Thu Feb 23, 2006 2:06 am    Post subject: Re: About templates Reply with quote

Ema wrote:
Quote:
Hi, I'm looking for a writing technique that would allow me to specify
which kind of <typename T> one template function can accept: Eg:

In case i have :

template<typename T> inline void doSomething(const T& a, const T& b)
{
...
...
}

and if I'd like to have it defined just for 'double' and 'int', how
could i specify that on the upper declaration, avoiding to full
specialize 'doSomething' for every T i need to be specialized?

Does exist a command that can limit the different values that T can be?

No. What you could do is write your two functions, one for 'int', the
other for 'double', and make them _call_ the 'doSomething' template while
making 'doSomething' _template_ unavailable to the user.

V
--
Please remove capital As from my address when replying by mail

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Alf P. Steinbach
Guest





PostPosted: Thu Feb 23, 2006 11:06 am    Post subject: Re: About templates Reply with quote

* Ema:
Quote:
Hi, I'm looking for a writing technique that would allow me to specify
which kind of <typename T> one template function can accept: Eg:

In case i have :

template<typename T> inline void doSomething(const T& a, const T& b)
{
...
...
}

and if I'd like to have it defined just for 'double' and 'int', how
could i specify that on the upper declaration, avoiding to full
specialize 'doSomething' for every T i need to be specialized?

Does exist a command that can limit the different values that T can be?

In addition to the suggestions put forward so far (boost::enable_if, and
implementing the relevant specializations as simple forwarders) you can
use a compile time assertion -- which is what boost::enable_if amounts
to -- and you can use a runtime check of type T using 'typeid', and
you can use the time-honored technique of simply /documenting/ the
restriction, e.g. a comment "to be used only with T as int or double".

But why would you want to restrict the template that way? If it
compiles for some type T, then presumably it works for type T. And if
it doesn't work for a type T, then presumably it doesn't compile for T.
Well, OK, I can think of some situations. But not for the set of
types int and double allowed.

On the other hand, this is currently a deficiency in the language,
because although you can express a constraint on some template
parameter, you don't reap the possible benefits. Language-supported
constrained generics (templates) make possible such things as templated
virtual member functions. I wonder how this is in C++/CLI?

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
kwikius
Guest





PostPosted: Thu Feb 23, 2006 12:06 pm    Post subject: Re: About templates Reply with quote

kwikius wrote:

[...]

Quote:
You can overload (functions are overloaded rather than specialized) the
function or use boost::enable_if which can help if you need to avoid
unwanted implicit conversions

[snip my previous example]

Carl Barrons version in this thread using mpl::contains, is much cooler
and preferable to mine using mpl::or_ and is_same, because its simpler
to extend to a large number of excluded types.

Nice one Carl!

regards
Andy Little


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Ema
Guest





PostPosted: Thu Feb 23, 2006 1:06 pm    Post subject: Re: About templates Reply with quote

Thanks Carl (and you others too Wink ).

I think this tag technique is better (and simpler) than others (boost's
one is kinda same).
Anyway I thought this could be done without these nice tricks!

Correct me if I'm wrong, but using the before method would not affect
performance in any way right!?!?
I can't use typeid and RTTI because of _very_ _very_ bad performance
(the functions I have to sitck with are binary serialization functions
that need to work just for basic types).

Thanks again,
Ema.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
James Hopkin
Guest





PostPosted: Thu Feb 23, 2006 2:06 pm    Post subject: Re: About templates Reply with quote

Alf P. Steinbach wrote:
Quote:
you can use a compile time assertion -- which is what
boost::enable_if amounts to

There's an important difference. enable_if removes unsuitable
instantiations from the overload set. The following example points out
the consequences of this better than I can put into words:

// Restricted template
template <class C>
typename enable_if<is_same<C, int>::value>::type
f(C);

// Additional overload
void f(double);

Imagine passing a float to f. In this example, it gets passed to
f(double). With static_asserts instead of enable_if, the template is
instantiated and fails to compile.

For completeness, I'll point out that there's also a difference between
Victor's forwarding solution and enable_if: the forwarding functions
allow user conversions on parameters. I think this is normally the
expected behaviour, so I would probably do it that way.


James


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
kwikius
Guest





PostPosted: Thu Feb 23, 2006 3:06 pm    Post subject: Re: About templates Reply with quote

Ema wrote:
Quote:
Thanks Carl (and you others too Wink ).

I think this tag technique is better (and simpler) than others (boost's
one is kinda same).
Anyway I thought this could be done without these nice tricks!

Correct me if I'm wrong, but using the before method would not affect
performance in any way right!?!?
I can't use typeid and RTTI because of _very_ _very_ bad performance
(the functions I have to sitck with are binary serialization functions
that need to work just for basic types).

Thanks again,
Ema.

BTW Carl made one typo, which is not putting 'typename' before a nested
type in a template (Corrected below). Other than that the function can
be written in two ways using enable_if (which uses incidentally exactly
the same trick used by tag above).Of the two I prefer the first, (1)
because its easier to read and (2)because it uses 1 less function
parameter . (I'm not sure its as portable to older compilers though and
that is 1 problem, that it needs a good compiler)
AFAIK the technique is called 'constrained genericity' and is an
example of use of SFINAE (substitution failure is not an error). There
is no penalty in runtime performance compared to unconstrained
templates:

#include <boost/shared_ptr.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/utility/enable_if.hpp>

/* knock out based on return type*/
template <typename T>
inline
typename boost::enable_if <
boost::mpl::contains <
boost::mpl::vector<int,double>,
T
Quote:

::type
doSomething1(const T &a,const T &b)

{
}

/* knock out based on unused argument*/
template <typename T>
inline
void
doSomething2(const T &a,const T &b,
typename boost::enable_if <
boost::mpl::contains <
boost::mpl::vector<int,double>,
T
Quote:

::type * = 0)
{

}

int main()
{
doSomething1(1,1);
doSomething2(1,1);
doSomething1(1L,1L);
doSomething2(1L,1L);
}

regards
Andy Little


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Alf P. Steinbach
Guest





PostPosted: Thu Feb 23, 2006 7:06 pm    Post subject: Re: About templates Reply with quote

* James Hopkin:
Quote:
* Alf P. Steinbach:
you can use a compile time assertion -- which is what
boost::enable_if amounts to

There's an important difference. enable_if removes unsuitable
instantiations from the overload set. The following example points out
the consequences of this better than I can put into words:

// Restricted template
template <class C
typename enable_if<is_same<C, int>::value>::type
f(C);

// Additional overload
void f(double);

Imagine passing a float to f. In this example, it gets passed to
f(double). With static_asserts instead of enable_if, the template is
instantiated and fails to compile.

Ah, yes, the subtletites of SFINAE! Wink One learns something every day,
this is great stuff, and I'm ashamed for not knowing. Especially since
it's not exactly new.

Btw., the acronym SFINAE is finally in the clc++ FAQ, but unfortunately
not yet in Bjarne's terminology FAQ / glossary (perhaps he thought I was
joking when I suggested that he include SFINAE -- it must be the most
ugly acronym ever invented! Smile ).

And btw2., a small typo correction, for those who would like to try this
out at once, the above should be like

typename enable_if< is_same<C, int> >::type

with no "::value".

Cheers,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Ulrich Eckhardt
Guest





PostPosted: Thu Feb 23, 2006 7:06 pm    Post subject: Re: About templates Reply with quote

Ema wrote:
Quote:
Correct me if I'm wrong, but using the before method [discrimitating
types via template metaprogramming] would not affect
performance in any way right!?!?

Yes it does, it sometimes puts quite some strain on compilers. That cost is
at compile-time though, not at runtime.

Quote:
I can't use typeid and RTTI because of _very_ _very_ bad performance
(the functions I have to sitck with are binary serialization functions
that need to work just for basic types).

RTTI in general is a runtime feature, so this is not used here.

Uli


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
kwikius
Guest





PostPosted: Fri Feb 24, 2006 3:06 am    Post subject: Re: About templates Reply with quote

Alf P. Steinbach wrote:

Quote:
But why would you want to restrict the template that way? If it
compiles for some type T, then presumably it works for type T. And if
it doesn't work for a type T, then presumably it doesn't compile for T.

The other nice feature of enable_if is that it gives an error message
pointing at the code where the user tried to instantate it rather than
spewing forth pages of what can only be described as compiler diarrhoea
with the last part pointing at the place where the user error occurred.
The code at the end produces the two error messages here. The
complexity of the second increases as the complexity of the template
increases of course.

regards
Andy Little

//error message from foo1 (enable_if)

Compiling...
test.cpp
test.cpp(24) : error C2893: Failed to specialize function template
'boost::enable_if<boost::is_same<T,int>>::type foo1(const T)'
With the following template arguments:
'double'

//error message from foo2 . Let compiler find error in body:

Compiling...
test.cpp
test.cpp(1Cool : error C2057: expected constant expression
test.cpp(25) : see reference to function template instantiation
'void foo2<double>(T)' being compiled
with
[
T=double
]
test.cpp(1Cool : error C2466: cannot allocate an array of constant size 0

----------code---------------
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>

template <typename T>
inline
typename boost::enable_if <
boost::is_same<T,int>
Quote:
::type
foo1(const T t)

{
double ar[t] = {1,2} ;
}

template <typename T>
inline void foo2(T t)
{
double ar[t] = {1,2};
}

int main()
{
//**********************
//uncomment out one or other to compare error messages
//*****************

// foo1(2.);
// foo2(2.);
}

regards
Andy Little


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.