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 

Template Question

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Suki
Guest





PostPosted: Thu Oct 27, 2005 10:37 am    Post subject: Template Question Reply with quote



Hi,
I'm writing a templated class, and i dont want to use the class
otherthan for some predetermined types, say, int, double etc.

This class has no meaning for typenames other than those few.

=========================
template <class T>
myClass {....} ;

myClass<int> intClass ;
myClass<float> floatClass ;
myClass<char> charClass ;
=========================

The compiler should not complain for the first 2 instantiations, but
should bail out at the 3rd instantiation (charClass). Is there any way
i
can achieve this, using standard c++ or boost.

I've tried explicit template instantiation, (by passing a flag to my
compiler), but in that case, i've to do that for every class

suppose i try to invoke
std::vector <someOtherClass> someVector;

I've to instantiate this also explicitly. (which is a problem for me,
because, I use a lot of standard library, and its a pain for me to
instantiate every time.

Also, if i do the above, i can always instantiate myClass also like
this.

template class myClass <someOtherClass> ;

and which i want to avoid this..

to summarize my question,
is there any way i can restrict the compiler to accept only few type
names for my templated class (i.e., using standard c++ or boost)


Thanks,
Surya


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

Back to top
Kai-Uwe Bux
Guest





PostPosted: Thu Oct 27, 2005 11:06 am    Post subject: Re: Template Question Reply with quote



Suki wrote:

Quote:
Hi,
I'm writing a templated class, and i dont want to use the class
otherthan for some predetermined types, say, int, double etc.

This class has no meaning for typenames other than those few.

=========================
template <class T
myClass {....} ;

myClass myClass<float> floatClass ;
myClass<char> charClass ;
=========================

The compiler should not complain for the first 2 instantiations, but
should bail out at the 3rd instantiation (charClass). Is there any way
i
can achieve this, using standard c++ or boost.
[snip]


What about:


template < typename bad_class >
struct bad_class_flag;

template <>
struct bad_class_flag<int> {};

template <>
struct bad_class_flag<float> {};



template < typename T >
class my_class : bad_class_flag<T> {

// my stuff goes here;

}; // my_class


int main ( void ) {
my_class<int> int_obj;
my_class<float> float_obj;
my_class<char> char_obj; // triggers an error
}



Best

Kai-Uwe Bux

Back to top
David Abrahams
Guest





PostPosted: Thu Oct 27, 2005 1:11 pm    Post subject: Re: Template Question Reply with quote



"Suki" <suryakiran.gullapalli (AT) gmail (DOT) com> writes:

Quote:
Hi,
I'm writing a templated class, and i dont want to use the class
otherthan for some predetermined types, say, int, double etc.

This class has no meaning for typenames other than those few.

=========================
template <class T
myClass {....} ;

myClass myClass<float> floatClass ;
myClass<char> charClass ;
=========================

The compiler should not complain for the first 2 instantiations, but
should bail out at the 3rd instantiation (charClass). Is there any way
i
can achieve this, using standard c++ or boost.

Declarative way:

template <class T>
struct myClass_impl
{
...
};

template <class T>
struct myClass;

template<>
myClass<int> : myClass_impl<int>
{};

template<>
myClass<float> : myClass_impl<float>
{};

template<>
myClass<char> : myClass_impl<char>
{};

Imperative way:

#include <boost/mpl/or.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>

template <class T>
struct myClass
{
BOOST_MPL_ASSERT((boost::mpl::or_<
boost::is_same , boost::is_same<T,float>
, boost::is_same<T,char>
Quote:
));

... // your class implementation here.
};

Quote:
to summarize my question,
is there any way i can restrict the compiler to accept only few type
names for my templated class (i.e., using standard c++ or boost)

HTH,

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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


Back to top
Tony Delroy
Guest





PostPosted: Thu Oct 27, 2005 1:12 pm    Post subject: Re: Template Question Reply with quote

Hi Surya,

One easy solution is to use a second template, the only purpose of
which is to break My_Class's code when a specialisation doesn't exist.
A lean approach customised to your immediate requirement is:

template <typename T>
class My_Class_Restriction
{
My_Class_Traits(); // note: private constructor
};

template <>
struct My_Class_Restriction<int>
{
};

template <>
struct My_Class_Restriction<double>
{
};

template <typename T>
class My_Class : My_Class_Restriction<T>
{
};

int main()
{
My_Class<int> mci;
My_Class<double> mcd;
My_Class<float> mcf; // breaks
}

But, more generally, you may want to put other things in the additional
class, and consider it a more general "traits" class. You'll find
information about traits on the web or in any half-way-reasonable C++
book.

template <typename T>
struct My_Class_Traits
{
};

template <>
struct My_Class_Traits<int>
{
static inline void is_supported() { }
};

template <>
struct My_Class_Traits<double>
{
static inline void is_supported() { }
};

template <typename T>
class My_Class
{
public:
My_Class()
{
My_Class_Traits<T>::is_supported();
}
};

int main()
{
My_Class<int> mci;
My_Class<double> mcd;
My_Class<float> mcf;
}

Cheers,

Tony


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

Back to top
Greg Herlihy
Guest





PostPosted: Thu Oct 27, 2005 4:39 pm    Post subject: Re: Template Question Reply with quote

Suki wrote:
Quote:
Hi,
I'm writing a templated class, and i dont want to use the class
otherthan for some predetermined types, say, int, double etc.

This class has no meaning for typenames other than those few.

=========================
template <class T
myClass {....} ;

myClass myClass<float> floatClass ;
myClass<char> charClass ;
=========================

The compiler should not complain for the first 2 instantiations, but
should bail out at the 3rd instantiation (charClass). Is there any way
i
can achieve this, using standard c++ or boost.

I've tried explicit template instantiation, (by passing a flag to my
compiler), but in that case, i've to do that for every class

suppose i try to invoke
std::vector <someOtherClass> someVector;

I've to instantiate this also explicitly. (which is a problem for me,
because, I use a lot of standard library, and its a pain for me to
instantiate every time.

Also, if i do the above, i can always instantiate myClass also like
this.

template class myClass <someOtherClass> ;

and which i want to avoid this..

to summarize my question,
is there any way i can restrict the compiler to accept only few type
names for my templated class (i.e., using standard c++ or boost)

First, I would not recommend turning off implicit template
instantiation. The aim here is really not to selectively instantiate -
but to selectively specialize - the template. If the class template is
specialized only for the approved types then only those types will be
able to instantiate the template successfully.

Along these lines, the simplistic solution would be to specialize the
template for each approved type:

template <class T>
class MyClass; // not defined

template <>
class MyClass<int>
{
...
};

template <>
class MyClass<float>
{
...
};

While this technique may be manageable for a few classes and a simple
template, the duplication of the template across each type makes
maintainence inconvenient and error-prone.

Fortunately, C++ allows templates and inheritance to be used together.
And it is this combination that leads to a much more maintainable
solution.

First, declare a base class template that implements the complete
template but whose constructor is protected:

template <class T>
class BaseClass
{
protected:
BaseClass();
public:
... // implement entire template here
};

Next declare (but do not define) the MyClass class template:

template <class T>
class MyClass;

Finally, specialize MyClass for each approved type, as above. Only this
time, the specialization will inherit from the BaseClass template to
obtain the the desired implementation for its type:

template <>
MyClass<int> : public BaseClass<int>
{
public:
MyClass();
...
};

This mechanism prevents anyone from inadvertently instantiating a
MyClass for a non-specialized type and from directly instantiating a
BaseClass for any type.

But one has to wonder whether discouraging the instantiation of
MyClass<char> is really worth going to such lengths. After all, if
MyClass<char> is a plausible specialization, than it probably should be
allowed. On the other hand, if MyClass<char> makes no sense, then
simply relying on the fact that there would never be a good reason to
instantiate MyClass<char> should be a sufficient deterrent. Lastly, it
is always possible to document the template class and list its
supported types. And then the matter would simply rely on each client's
own good judgment.

Greg


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


Back to top
Old Wolf
Guest





PostPosted: Fri Oct 28, 2005 9:07 am    Post subject: Re: Template Question Reply with quote

Suki wrote:
Quote:
Hi,
I'm writing a templated class, and i dont want to use the class
otherthan for some predetermined types, say, int, double etc.

Here's a simple way:

template<typename T> struct Foo;
template<> struct Foo<int> { };
template<> struct Foo<float> { };

template<typename T>
struct X: private Foo<T>
{
};

int main()
{
X<int> a;
X<float> b;
X<char> c;
}


g++ b.cc -o b
b.cc: In instantiation of `X<char>':
b.cc:14: instantiated from here
b.cc:7: error: invalid use of undefined type `struct Foo<char>'


[ 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: Fri Oct 28, 2005 9:38 am    Post subject: Re: Template Question Reply with quote

Suki <suryakiran.gullapalli (AT) gmail (DOT) com> wrote:

Quote:
Hi,
I'm writing a templated class, and i dont want to use the class
otherthan for some predetermined types, say, int, double etc.

This class has no meaning for typenames other than those few.

=========================
template <class T
myClass {....} ;

myClass myClass<float> floatClass ;
myClass<char> charClass ;
=========================

The compiler should not complain for the first 2 instantiations, but
should bail out at the 3rd instantiation (charClass). Is there any way

The easiest way is to use an additional template that is declared

for all types but only specialized for the desired types as an empty
classs, then MyClass inherits this 'trait class'

template <class T> struct MyClassSupports;
// specialize it for only the desired types

template <> struct MyClassSupports<int>{};
template <> struct MyClassSupports<double>{};

// finally
template <class T>
class MyClass:public MyClassSupports<T>
{
// your class
};

This inheritance has nothing to do with oop it is a method to get
a compiler error if the template argument is different from int or
double.

can be done with boost::enable_if and boost's mpl library if the
# of valid types is fairly large or you don't wnat to pollute your
namespace[s] with extra types soley for compiler checks.

template <class T>
class MyClass:public boost::enable_if
<
boost::mpl::contains
<
boost::mpl::vector T
Quote:
,
boost::mpl::empty_base
::type
{

// your definition
};

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


Back to top
lfeiman888@gmail.com
Guest





PostPosted: Tue Nov 01, 2005 9:46 am    Post subject: Re: Template Question Reply with quote

Declarative way:

template <class T>
struct myClass_impl
{
...
};


template <class T>
struct myClass;


template<>
myClass<int> : myClass_impl<int>
{};


template<>
myClass<float> : myClass_impl<float>
{};


template<>
myClass<char> : myClass_impl<char>
{};


But I cannot compile these code under my compiler(vc 2003).Sad
anyone here can???


[ 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: Tue Nov 01, 2005 1:02 pm    Post subject: Re: Template Question Reply with quote


[email]lfeiman888 (AT) gmail (DOT) com[/email] wrote:
Quote:
Declarative way:

template <class T
struct myClass_impl
{
...
};


template struct myClass;


template
myClass {};


template
myClass {};


template
myClass {};


But I cannot compile these code under my compiler(vc 2003).Sad
anyone here can???

Each specialisation should have 'struct' after template<>. Is this a
subtle hint from David Abrahams that because we already know what
myClass is that 'struct' is in fact redundant in the above
specialisations ;-)

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
Greg Herlihy
Guest





PostPosted: Tue Nov 01, 2005 1:02 pm    Post subject: Re: Template Question Reply with quote


[email]lfeiman888 (AT) gmail (DOT) com[/email] wrote:
Quote:
Declarative way:

template <class T
struct myClass_impl
{
...
};


template struct myClass;


template
myClass {};


template
myClass {};


template
myClass {};


But I cannot compile these code under my compiler(vc 2003).Sad
anyone here can???

Just supply the missing keywords where they are needed:

template struct myClass_impl
{
// ...
};

template <class T>
struct myClass;

template<>
struct myClass<int> : public myClass_impl<int>
{};

template<>
struct myClass<float> : public myClass_impl<float>
{};

template<>
struct myClass<char> : public myClass_impl<char>
{};

Greg


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


Back to top
David Abrahams
Guest





PostPosted: Tue Nov 01, 2005 2:17 pm    Post subject: Re: Template Question Reply with quote

"kwikius" <andy (AT) servocomm (DOT) freeserve.co.uk> writes:

Quote:
lfeiman888 (AT) gmail (DOT) com wrote:
Declarative way:

template <class T
struct myClass_impl
{
...
};


template struct myClass;


template
myClass {};


template
myClass {};


template
myClass {};


But I cannot compile these code under my compiler(vc 2003).Sad
anyone here can???

Each specialisation should have 'struct' after template<>. Is this a
subtle hint from David Abrahams that because we already know what
myClass is that 'struct' is in fact redundant in the above
specialisations Wink

No, it's a subtle hint that I'm as prone to dumb mistakes as anyone
else ;-)

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

[ 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 (comp.lang.c++) 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.