473,657 Members | 2,753 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

limiting a template class to certain types ?

Is it possible to limit a template class to certain types only. I found
a few things on the net but nothing seems to apply at compile time.

template <typename T>
class AClass
{
public:
AClass() {}
};

AClass<floatflo atSomethng; // yes it's fine
AClass<intintSo mething; // no we don't want to allow the creation of
that object

Thank you, -mark

Jul 11 '06 #1
10 10209
ma*****@yahoo.c om wrote:
Is it possible to limit a template class to certain types only. I found
a few things on the net but nothing seems to apply at compile time.

template <typename T>
class AClass
{
public:
AClass() {}
};

AClass<floatflo atSomethng; // yes it's fine
AClass<intintSo mething; // no we don't want to allow the creation of
that object
template<typena me T>
class AClass {
public:
AClass() { }
};

template<class AClass<int>;

int main()
{
AClass<doublead ;
AClass<intai; // error
}

Jul 11 '06 #2
ma*****@yahoo.c om wrote:
Is it possible to limit a template class to certain types only. I
found a few things on the net but nothing seems to apply at compile
time.

template <typename T>
class AClass
{
public:
AClass() {}
};

AClass<floatflo atSomethng; // yes it's fine
AClass<intintSo mething; // no we don't want to allow the creation of
that object
The simplest way is probably hide the implementation of your template
type in a separate translation unit and use explicit instantiations
to stuff the same TU with the implementations of the class for some
specific types. A better way would be to design it so there is no
need to limit it.

Or you could do something like this (AKA "type traits"):

template<class Tclass allowed { enum { yes }; };

// then specialise it for the types that you allow:

template<class allowed<float{ public: enum { yes = 1 }; };
template<class allowed<double{ public: enum { yes = 1 }; };

// and last, use it:

template<typena me T>
class AClass
{
static const bool allowed = allowed<T>::yes ;

public:
AClass() {}
};

int main() {
AClass<floataf;
AClass<intaf; // error
}

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 11 '06 #3
ma*****@yahoo.c om posted:

AClass<floatflo atSomethng; // yes it's fine
AClass<intintSo mething; // no we don't want to allow the creation of

The examples on this page may interest you:

http://www.boost.org/doc/html/boost_staticassert.html

(However, one of the examples is dubious in that it should use
"numeric_limits <T>::digits" rather than "sizeof(T) * CHAR_BIT" ).

--

Frederick Gotham
Jul 11 '06 #4
Thanks everyone for your help !

Jul 12 '06 #5
Victor Bazarov wrote:
Or you could do something like this (AKA "type traits"):

template<class Tclass allowed { enum { yes }; };

// then specialise it for the types that you allow:

template<class allowed<float{ public: enum { yes = 1 }; };
template<class allowed<double{ public: enum { yes = 1 }; };

// and last, use it:

template<typena me T>
class AClass
{
static const bool allowed = allowed<T>::yes ;

public:
AClass() {}
};

int main() {
AClass<floataf;
AClass<intaf; // error
}
This works great for allowing certain templated classes to be used.
But what about functions and overloaded operators? For instance, if I
have a certain family of template classes, how could I overload an
operator so that it only acts on these classes? I'm thinking in
particular of boost::lambda, where they overload just about every
operator to work on the placeholders, but boost::spirit and many other
libraries do this sort of thing as well, even without the proposed
(TR2?) "concept" formalism.

To be more concrete. Suppose I have a predicate template of some sort,
either like your allowed<T>::yes enum, or maybe a bool
allowed_p<T>::v alue. Short of sticking all the allowed classes into an
unnamed namespace to restrict scope (since this allows classes from
global scope as well), how could I write this function

template<class T>
increment_retur n_type<T>::type operator++(T x);

so that T can ONLY be a class which satisfies the predicate?

Thanks,
steve hicks

Jul 12 '06 #6
Steve Hicks wrote:
[..] Suppose I have a predicate template of some
sort, either like your allowed<T>::yes enum, or maybe a bool
allowed_p<T>::v alue. Short of sticking all the allowed classes into
an unnamed namespace to restrict scope (since this allows classes from
global scope as well), how could I write this function

template<class T>
increment_retur n_type<T>::type operator++(T x);

so that T can ONLY be a class which satisfies the predicate?
I probably don't understand the requirements. Could you please provide
a C++ illustration (even if it doesn't compile)?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 12 '06 #7
To be more concrete. Suppose I have a predicate template of some sort,
either like your allowed<T>::yes enum, or maybe a bool
allowed_p<T>::v alue. Short of sticking all the allowed classes into an
unnamed namespace to restrict scope (since this allows classes from
global scope as well), how could I write this function

template<class T>
increment_retur n_type<T>::type operator++(T x);

so that T can ONLY be a class which satisfies the predicate?
Just add a test, using the typedef T type; trick again.

template<bool bstruct test; // undefined
template<struct test<true{ }; // defined specialization
template<typena me T, bool b>
struct test_identity<T : test<b{
typedef T type;
};

template<class T>
increment_retur n_type<test_ide ntity<T,
allowed_p<T>::v alue>::type>::t ype
operator++(T x);

HTH,
Michiel Salters

Jul 12 '06 #8
Mi************* @tomtom.com wrote:
Just add a test, using the typedef T type; trick again.

template<bool bstruct test; // undefined
template<struct test<true{ }; // defined specialization
template<typena me T, bool b>
struct test_identity<T : test<b{
typedef T type;
};

template<class T>
increment_retur n_type<test_ide ntity<T,
allowed_p<T>::v alue>::type>::t ype
operator++(T x);
That's a neat trick. Unfortunately, it doesn't quite do what I need.
Here is a small example:

/* BEGIN CODE */
#include <iostream>
template <bool bstruct test;
template <struct test<true{ };
template <class T, bool b>
struct test_identity : test<b{
typedef T type;
};
template <class Tstruct is_callable {
static const bool value = false;
};

template <class Tclass Constant {
T value;
public:
Constant(T t) : value(t) { }
void operator()()
{ std::cout << "value: " << value << std::endl; }
};
template <class Tstruct is_callable<Con stant<T {
static const bool value = true;
};

// T1 and T2 must be callable
template <class T1, class T2class Sum {
T1 t1; T2 t2;
public:
Sum(T1 _t1, T2 _t2) : t1(_t1), t2(_t2) { }
void operator()() { t1(); t2(); }
};

template <class T1,class T2>
typename test_identity<S um<T1,T2>,is_ca llable<T1>::val ue &&
is_callable<T2> ::value>::type
operator+(T1 t1,T2 t2) {
return Sum<T1,T2>(t1,t 2);
}
/* END CODE */

Basically, it only makes sense to have Sum<T1,T2if T1 and T2 are both
callable. I could easily insert a Boost static assert to ensure that
they are, but my issue is this: the overloaded operator+ still allows
any type to be sent to it, and then generates a compiler error if it's
not callable. So,

Constant<inta = 5; Constant<double b = 10.3;
(a+b)();

works, but

Constant<inta = 5;
(a+10.3)();

fails to compile, despite my implicit constructor, since it tries to
make Sum<Constant<in t>,intand in doing so, tries to make
test<is_callabl e<int>::valuewh ich is undefined.

I tried one more thing:

template <class T1,class T2>
Sum<T1,T2operat or+(typename
test_identity<T 1,is_callable<T 1>::value>::typ e t1,
typename test_identity<T 2,is_callable<T 2>::value>::typ e t2) {
return Sum<T1,T2>(t1,t 2);
}

but then my main() wouldn't compile because it couldn't implicitly
figure out that test_identity<T 1,...>::type was really just T1.
Hopefully I've made my problem more clear. Thanks to those still
paying attention. Any ideas?

steve

Jul 13 '06 #9
* Steve Hicks:
Mi************* @tomtom.com wrote:
>Just add a test, using the typedef T type; trick again.

template<boo l bstruct test; // undefined
template<struc t test<true{ }; // defined specialization
template<typen ame T, bool b>
struct test_identity<T : test<b{
typedef T type;
};

template<cla ss T>
increment_retu rn_type<test_id entity<T,
allowed_p<T>:: value>::type>:: type
operator++(T x);

That's a neat trick. Unfortunately, it doesn't quite do what I need.
Here is a small example:

/* BEGIN CODE */
#include <iostream>
template <bool bstruct test;
template <struct test<true{ };
template <class T, bool b>
struct test_identity : test<b{
typedef T type;
};
template <class Tstruct is_callable {
static const bool value = false;
};

template <class Tclass Constant {
T value;
public:
Constant(T t) : value(t) { }
void operator()()
{ std::cout << "value: " << value << std::endl; }
};
template <class Tstruct is_callable<Con stant<T {
static const bool value = true;
};

// T1 and T2 must be callable
template <class T1, class T2class Sum {
T1 t1; T2 t2;
public:
Sum(T1 _t1, T2 _t2) : t1(_t1), t2(_t2) { }
void operator()() { t1(); t2(); }
};

template <class T1,class T2>
typename test_identity<S um<T1,T2>,is_ca llable<T1>::val ue &&
is_callable<T2> ::value>::type
operator+(T1 t1,T2 t2) {
return Sum<T1,T2>(t1,t 2);
}
/* END CODE */

Basically, it only makes sense to have Sum<T1,T2if T1 and T2 are both
callable. I could easily insert a Boost static assert to ensure that
they are, but my issue is this: the overloaded operator+ still allows
any type to be sent to it, and then generates a compiler error if it's
not callable. So,

Constant<inta = 5; Constant<double b = 10.3;
(a+b)();

works, but

Constant<inta = 5;
(a+10.3)();

fails to compile, despite my implicit constructor, since it tries to
make Sum<Constant<in t>,intand in doing so, tries to make
test<is_callabl e<int>::valuewh ich is undefined.
You could try

template <class T1,class T2>
typename boost::enable_i f_c<
is_callable<T1> ::value && is_callable<T2> ::value,
Sum<T1,T2>
>::type
operator+(T1 t1,T2 t2) { return Sum<T1,T2>(t1,t 2); }

which I believe is specifically what you're asking for.

However, for your chosen problem this leads to a little (contained)
combinatorial explosion: it answers the question but does not solve the
problem in a reasonable way, and that's because you're not asking about
the problem but about a particular non-working way to solve it.

Better to simply make sure that anything that can behave as a constant
has a value:

#include <iostream>

template <class Tclass Constant {
T value;
public:
Constant(T t) : value(t) { }
double operator()() const
{ std::cout << "value: " << value << std::endl; return value; }
};

template< typename T T valueOf( T const& x )
{ return x; }
template< typename T T valueOf( Constant<Tconst & x )
{ return static_cast<T>( x() ); } // Cast due to use of 'double'.

template <class T1, class T2class Sum {
T1 t1; T2 t2;
public:
Sum(T1 _t1, T2 _t2) : t1(_t1), t2(_t2) { }
double operator()() const { return valueOf(t1) + valueOf(t2); }
};

template <class T1,class T2>
Sum<T1,T2operat or+(T1 t1,T2 t2) { return Sum<T1,T2>(t1,t 2); }

int main()
{
Constant<inta = 5; Constant<double b = 10.3;

std::cout << (a+b)() << std::endl;
std::cout << (a+10.3)() << std::endl;
}

Hth.

--
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?
Jul 13 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
2274
by: Kartsev | last post by:
hello! how to limit class template parameter T in template <class T> SomeClass { /*.... */ }
8
1952
by: Thomas Heller | last post by:
I need to convert C preprocessor definitions into python code. The definitions are dumped out of gccxml (see http://www.gccxml.org) , running over the windows header files (for example). This creates output like this (some excerpts): #define DATABITS_8 ((WORD)0x0008) #define KEY_WRITE ((STANDARD_RIGHTS_WRITE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY) & (~SYNCHRONIZE)) #define MS_NBF "MNBF" #define PSN_FIRST (0U-200U)
3
2725
by: case2005 | last post by:
Can anyone help with the following, I don't know if it's possible, but I'm certain there must be a standard way of dealing with this. I have the following: template<typename FooBar, typename Foo> class Bar { private: Foo foo;
9
2725
by: Ann Huxtable | last post by:
I have the following code segment - which compiles fine. I'm just worried I may get run time probs - because it looks like the functions are being overloaded by the return types?. Is this Ok: ? template <class T1, class T2> int getValue( T1 col, T2 row ) ; template <class T1, class T2> double getValue( T1 col, T2 row ) ;
3
1315
by: Alfonso Morra | last post by:
if I have a base class A declared as: template <typename T1, typename T2, my_enum_1=NONE, my_enum_2=ALL, bool=true> class A { .... };
12
2612
by: mlimber | last post by:
This is a repost (with slight modifications) from comp.lang.c++.moderated in an effort to get some response. I am using Loki's Factory as presented in _Modern C++ Design_ for message passing in an embedded environment with multiple processors. I created a policy for classes, which, I had hoped, would automatically register the class with the appropriate factory: // In some header file... #include <cassert>
19
2552
by: n.torrey.pines | last post by:
I have the following tree definition: template<typename T> struct tree { T first; vector<tree<T second; // branches }; which compiles successfully. What I'd like to do though is to use another template like 'pair', because I might have a bunch of useful
32
2714
by: Stephen Horne | last post by:
I've been using Visual C++ 2003 for some time, and recently started working on making my code compile in GCC and MinGW. I hit on lots of unexpected problems which boil down to the same template issue. A noddy mixin layer example should illustrate the issue... class Base { protected: int m_Field;
9
17531
by: Marco Nef | last post by:
Hi there I'm looking for a template class that converts the template argument to a string, so something like the following should work: Convert<float>::Get() == "float"; Convert<3>::Get() == "3"; Convert<HelloWorld>::Get() == "HelloWorld"; The reason I need this is that in our design every class of a certain
0
8297
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8816
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8717
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8498
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8600
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7311
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5629
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
1
2726
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1600
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.