 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Valery Aronov Guest
|
Posted: Sun Oct 30, 2005 1:22 pm Post subject: not permitted template types |
|
|
I am looking for a way to specify this for a class template:
<T1 and T2 template parameters only are permitted with this class
template>
I would like then a compiler to report explicitly about an attempt to
use a not permitted type.
It would've been useful in our code where we have some templated facade
classes to the variety of underlying types. The facade template adds
extra functionality to the underlying types and the set of underlying
types is restricted. If achievable it would be more
convenient/expressive than the coming concept specification feature
(http://microsoft.sitestream.com/PDC05/TLN/TLN309_files/Default.htm#nopreload=1&autostart=1,
for example), but would serve the same purpose of type checking and
better error messages. We also need something now when the concepts are
not implemented by major compilers.
Our users (actuaries) write their formulas in C++ and compile them with
our library, but they are not supposed to know C++ types of the
modelling system data (template classes which are too technical for
them) and would be terrified by the error messages referring to
template classes.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Thomas Richter Guest
|
Posted: Sun Oct 30, 2005 3:00 pm Post subject: Re: not permitted template types |
|
|
Valery Aronov wrote:
| Quote: | I am looking for a way to specify this for a class template:
T1 and T2 template parameters only are permitted with this class
template
I would like then a compiler to report explicitly about an attempt to
use a not permitted type.
|
What about a type-traits approach?
Define a class
template <typename Entry> struct ElementTraits {
// Not valid. Create a compiler error if this is
// used.
};
then specialize for all "acceptable" types as follows:
template <typename T> struct ElementTraits<T *> {
enum { isValid = true };
};
(i.e. here "all pointers" are fine)
or
template <> struct ElementTraits<T1> {
enum { isValid = true };
};
template <> struct ElementTraits<T2> {
enum { isValid = true };
};
in your case. Then, within your class:
template <typename Entry> class MyClass {
//
// Members go here...
public:
MyClass(void)
{
assert(ElementTraits<Entry>::isValid);
}
}
will trigger a compile-time warning since ElementTraits will not have
a member isValid except for the specialized classes.
So long,
Thomas
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Alec Ross Guest
|
Posted: Mon Oct 31, 2005 10:49 am Post subject: Re: not permitted template types |
|
|
In article <1130642411.905019.171820 (AT) g43g2000cwa (DOT) googlegroups.com>,
Valery Aronov <valerka (AT) gmail (DOT) com> writes
| Quote: | I am looking for a way to specify this for a class template:
T1 and T2 template parameters only are permitted with this class
template
See the replies by David Abrahams and others to the recent thread |
"Template Question" on this group.
--
Alec Ross
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Valentin Samko Guest
|
Posted: Mon Oct 31, 2005 10:52 am Post subject: Re: not permitted template types |
|
|
Valery Aronov wrote:
| Quote: | I am looking for a way to specify this for a class template:
T1 and T2 template parameters only are permitted with this class
template
|
So, you want a compile time error if someone instantiates your class template with a
template parameter which is not in your list?
Option 1. Only specialise your class template for your parameters. You can also add a
proxy class to avoid repeating the same code in each specialisation. For example:
template<class T>
class Implementation { ... };
template<class T> class Proxy;
template<>
class Proxy<AllowedTemplateParam1> : public Implementation<AllowedTemplateParam1> {};
class Proxy<AllowedTemplateParam2> : public Implementation<AllowedTemplateParam2> {};
Which will generate a nice readable compile time error if your proxy for your template
parameter is not specialised.
Option 2. Use boost enable_if to generate a compile time error (which is most likely to be
completely unreadable and is most likely to slow your compiler down)
struct dummy {};
template<class T>
class YourTemplate : public
typename
boost::enable_if_c<
boost::mpl::or_<
boost::is_same
boost::is_same<T, AllowedTemplateParam2>
};
Option 3. More readable variant of 2.
template<class T>
class YourTemplate
{
BOOST_MPL_ASSERT((
boost::mpl::or_<
boost::is_same
boost::is_same<T, AllowedTemplateParam2>
Unless your project already depends on boost::mpl and/or boost::mpl is acceptable for your
project, I would use Option 1. Otherwise, use Option 3, as it is more explicit about what
you are doing.
--
Valentin Samko - http://www.valentinsamko.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dan McLeran Guest
|
Posted: Tue Nov 01, 2005 9:49 am Post subject: Re: not permitted template types |
|
|
A simple solution:
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
BOOST_STATIC_ASSERT((boost::is_same<T, T1>::value) ||
(boost::is_same<T, T2>::value));
[ 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
|
Posted: Tue Nov 01, 2005 9:50 am Post subject: Re: not permitted template types |
|
|
Valentin Samko wrote:
[cut]
| Quote: | Option 2. Use boost enable_if to generate a compile time error (which is most likely to be
completely unreadable and is most likely to slow your compiler down)
struct dummy {};
template<class T
class YourTemplate : public
typename
boost::enable_if_c
boost::mpl::or_
boost::is_same
boost::is_same<T, AllowedTemplateParam2
,
dummy
::type
{
};
|
Actually the above is not optimal for eror messages. enable_if is meant
to be used as a spare parameter. e.g:
#include
#include <boost/mpl/or.hpp>
#include <boost/type_traits/is_same.hpp>
// forward decl YourTemplate with spare param as written
template <typename T, typename Enable = void>
struct YourTemplate;
// by default template parameters dont conform to is_my_concept , one
way is to derive from mpl::false_ to convey this
template <typename T>
struct is_my_concept : boost::mpl::false_{};
// specialise YourTemplate as follows
template<class T>
struct YourTemplate <
T,
typename boost::enable_if<
is_my_concept
// make is_my_concept true for any conforming types
template <>
struct is_my_concept<int> : boost::mpl::true_{};
int main()
{
YourTemplate<int> v1;
YourTemplate<double> v2; // gives error message
}
In vc7.1 the error message using this technique is quite acceptable:
test.cpp(33): error C2079: 'v2' uses undefined struct 'YourTemplate<T>'
with
[
T=double
]
[cut]
| Quote: | Unless your project already depends on boost::mpl and/or boost::mpl is acceptable for your
project, I would use Option 1. Otherwise, use Option 3, as it is more explicit about what
you are doing.
|
Hopefully C++ will one day have concepts, in which case use of
enable_if is preferable in user code as it is ( a admittedly poor )
substitute for them.
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 |
|
 |
|
|
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
|
|