By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,273 Members | 1,032 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,273 IT Pros & Developers. It's quick & easy.

Template-Meta: Finding out whether a template-definition exists

P: n/a
Hi,

suppose we have

template< typename T >
struct X;

and some specializations:

template<>
struct X<A{};
template<>
struct X<B{};
template<>
struct X<B{};

Given a type 'U', is there a way to find out whether the
definition 'X<U>' exists? (The result should be a compile-
time constant, so that it can be used for specializing
other templates.)

Schobi

--
Sp******@gmx.de is never read
I'm HSchober at gmx dot de
"A patched buffer overflow doesn't mean that there's one less way attackers
can get into your system; it means that your design process was so lousy
that it permitted buffer overflows, and there are probably thousands more
lurking in your code."
Bruce Schneier
Sep 3 '07 #1
Share this Question
Share on Google+
16 Replies


P: n/a
On Sep 3, 2:13 pm, "Hendrik Schober" <SpamT...@gmx.dewrote:
Hi,

suppose we have

template< typename T >
struct X;

and some specializations:

template<>
struct X<A{};

template<>
struct X<B{};

template<>
struct X<B{};

Given a type 'U', is there a way to find out whether the
definition 'X<U>' exists? (The result should be a compile-
time constant, so that it can be used for specializing
other templates.)

Schobi

--
SpamT...@gmx.de is never read
I'm HSchober at gmx dot de
"A patched buffer overflow doesn't mean that there's one less way attackers
can get into your system; it means that your design process was so lousy
that it permitted buffer overflows, and there are probably thousands more
lurking in your code."
Bruce Schneier
IMHO

template< typename T >
struct X
{
enum { kIsSpecialized = false };
};

template<>
struct X< A >
{
enum { kIsSpecialized = true };
};

if you cannot touch the structs you might keep a manually updated
typelist ( a la Alexandrescu ) of the specialized types anche check if
a type is in the typelist...

I can't think of any other way ( so probably there are a thousands
more ... )
Sep 3 '07 #2

P: n/a
xt*********@gmail.com wrote:
On Sep 3, 2:13 pm, "Hendrik Schober" <SpamT...@gmx.dewrote:
>Hi,

suppose we have

template< typename T >
struct X;

and some specializations:

template<>
struct X<A{};

template<>
struct X<B{};

template<>
struct X<B{};

Given a type 'U', is there a way to find out whether the
definition 'X<U>' exists? (The result should be a compile-
time constant, so that it can be used for specializing
other templates.)

Schobi

--
SpamT...@gmx.de is never read
I'm HSchober at gmx dot de
"A patched buffer overflow doesn't mean that there's one less way attackers
can get into your system; it means that your design process was so lousy
that it permitted buffer overflows, and there are probably thousands more
lurking in your code."
Bruce Schneier

IMHO

template< typename T >
struct X
{
enum { kIsSpecialized = false };
};

template<>
struct X< A >
{
enum { kIsSpecialized = true };
};

if you cannot touch the structs you might keep a manually updated
what do you mean by "you cannot touch the structs"?
typelist ( a la Alexandrescu ) of the specialized types anche check if
a type is in the typelist...
what will the typelist contains?
I can't think of any other way ( so probably there are a thousands
more ... )


--
Thanks
Barry
Sep 3 '07 #3

P: n/a
On 2007-09-03 14:47, Barry wrote:
xt*********@gmail.com wrote:
>On Sep 3, 2:13 pm, "Hendrik Schober" <SpamT...@gmx.dewrote:
>>Hi,

suppose we have

template< typename T >
struct X;

and some specializations:

template<>
struct X<A{};

template<>
struct X<B{};

template<>
struct X<B{};

Given a type 'U', is there a way to find out whether the
definition 'X<U>' exists? (The result should be a compile-
time constant, so that it can be used for specializing
other templates.)

Schobi

--
SpamT...@gmx.de is never read
I'm HSchober at gmx dot de
"A patched buffer overflow doesn't mean that there's one less way attackers
can get into your system; it means that your design process was so lousy
that it permitted buffer overflows, and there are probably thousands more
lurking in your code."
Bruce Schneier

IMHO

template< typename T >
struct X
{
enum { kIsSpecialized = false };
};

template<>
struct X< A >
{
enum { kIsSpecialized = true };
};

if you cannot touch the structs you might keep a manually updated

what do you mean by "you cannot touch the structs"?
If you can't change the code containing the specialisations.
>typelist ( a la Alexandrescu ) of the specialized types anche check if
a type is in the typelist...

what will the typelist contains?
Once of each of the specialisations, in other words it should be a list
of all the specialisations.

--
Erik Wikström
Sep 3 '07 #4

P: n/a
On Sep 3, 2:47 pm, Barry <dhb2...@gmail.comwrote:
xtrigger...@gmail.com wrote:
On Sep 3, 2:13 pm, "Hendrik Schober" <SpamT...@gmx.dewrote:
Hi,
suppose we have
template< typename T >
struct X;
and some specializations:
template<>
struct X<A{};
template<>
struct X<B{};
template<>
struct X<B{};
Given a type 'U', is there a way to find out whether the
definition 'X<U>' exists? (The result should be a compile-
time constant, so that it can be used for specializing
other templates.)
Schobi
--
SpamT...@gmx.de is never read
I'm HSchober at gmx dot de
"A patched buffer overflow doesn't mean that there's one less way attackers
can get into your system; it means that your design process was so lousy
that it permitted buffer overflows, and there are probably thousands more
lurking in your code."
Bruce Schneier
IMHO
template< typename T >
struct X
{
enum { kIsSpecialized = false };
};
template<>
struct X< A >
{
enum { kIsSpecialized = true };
};
if you cannot touch the structs you might keep a manually updated

what do you mean by "you cannot touch the structs"?
typelist ( a la Alexandrescu ) of the specialized types anche check if
a type is in the typelist...

what will the typelist contains?
I can't think of any other way ( so probably there are a thousands
more ... )

--
Thanks
Barry- Hide quoted text -

- Show quoted text -
If the structs are made by someone else and you cannot insert an
enum...

you might do something like

typedef TypeListCreator< A, B, C, D >::tResult
typeListOfClassXYZSpecializations;

then you can check if a type is in there with something like

enum { kIsTypeASpecialized = ( TypeListIndexOf<
typeListOfClassXYZSpecializations, A >::kResult != 0 ) };

TypeListCreator and TypeListIndexOf are typelist handling classes a la
Alexandrescu.

Obviously the list must be manually updated so it is helpful just to
keep everything in one place...

Regards,
FB

Sep 3 '07 #5

P: n/a
Erik Wikström <Er***********@telia.comwrote:
On 2007-09-03 14:47, Barry wrote:
xt*********@gmail.com wrote:
On Sep 3, 2:13 pm, "Hendrik Schober" <SpamT...@gmx.dewrote:
[...]
if you cannot touch the structs you might keep a manually updated
what do you mean by "you cannot touch the structs"?

If you can't change the code containing the specialisations.
I can't.
typelist ( a la Alexandrescu ) of the specialized types anche check if
a type is in the typelist...
>
what will the typelist contains?

Once of each of the specialisations, in other words it should be a list
of all the specialisations.
I want to find out about it programmatically because
I don't want to hard-code it. So this doesn't help.

Schobi

--
Sp******@gmx.de is never read
I'm HSchober at gmx dot de
"A patched buffer overflow doesn't mean that there's one less way attackers
can get into your system; it means that your design process was so lousy
that it permitted buffer overflows, and there are probably thousands more
lurking in your code."
Bruce Schneier
Sep 3 '07 #6

P: n/a
xt*********@gmail.com wrote:
On Sep 3, 2:47 pm, Barry <dhb2...@gmail.comwrote:
>xtrigger...@gmail.com wrote:
>>On Sep 3, 2:13 pm, "Hendrik Schober" <SpamT...@gmx.dewrote:
Hi,
suppose we have
template< typename T >
struct X;
and some specializations:
template<>
struct X<A{};
template<>
struct X<B{};
template<>
struct X<B{};
Given a type 'U', is there a way to find out whether the
definition 'X<U>' exists? (The result should be a compile-
time constant, so that it can be used for specializing
other templates.)
Schobi
--
SpamT...@gmx.de is never read
I'm HSchober at gmx dot de
"A patched buffer overflow doesn't mean that there's one less way attackers
can get into your system; it means that your design process was so lousy
that it permitted buffer overflows, and there are probably thousands more
lurking in your code."
Bruce Schneier
IMHO
template< typename T >
struct X
{
enum { kIsSpecialized = false };
};
template<>
struct X< A >
{
enum { kIsSpecialized = true };
};
if you cannot touch the structs you might keep a manually updated
what do you mean by "you cannot touch the structs"?
>>typelist ( a la Alexandrescu ) of the specialized types anche check if
a type is in the typelist...
what will the typelist contains?
>>I can't think of any other way ( so probably there are a thousands
more ... )
--
Thanks
Barry- Hide quoted text -

- Show quoted text -

If the structs are made by someone else and you cannot insert an
enum...

you might do something like

typedef TypeListCreator< A, B, C, D >::tResult
typeListOfClassXYZSpecializations;

then you can check if a type is in there with something like

enum { kIsTypeASpecialized = ( TypeListIndexOf<
typeListOfClassXYZSpecializations, A >::kResult != 0 ) };
actually != -1, if our versions are the same here
well, the naming convention of Loki is quite different with mine

As I write
typedef LOKI_TYPELIST_2(X<int>, X<float>) SpecializedList;
BOOST_STATIC_ASSERT((Loki::TL::IndexOf<Specialized List, X<bool>
>::value) == -1);
>
TypeListCreator and TypeListIndexOf are typelist handling classes a la
Alexandrescu.

Obviously the list must be manually updated so it is helpful just to
keep everything in one place...

Regards,
FB

--
Thanks
Barry
Sep 3 '07 #7

P: n/a
On Sep 3, 3:39 pm, Barry <dhb2...@gmail.comwrote:
xtrigger...@gmail.com wrote:
On Sep 3, 2:47 pm, Barry <dhb2...@gmail.comwrote:
xtrigger...@gmail.com wrote:
On Sep 3, 2:13 pm, "Hendrik Schober" <SpamT...@gmx.dewrote:
Hi,
suppose we have
template< typename T >
struct X;
and some specializations:
template<>
struct X<A{};
template<>
struct X<B{};
template<>
struct X<B{};
Given a type 'U', is there a way to find out whether the
definition 'X<U>' exists? (The result should be a compile-
time constant, so that it can be used for specializing
other templates.)
Schobi
--
SpamT...@gmx.de is never read
I'm HSchober at gmx dot de
"A patched buffer overflow doesn't mean that there's one less way attackers
can get into your system; it means that your design process was so lousy
that it permitted buffer overflows, and there are probably thousands more
lurking in your code."
Bruce Schneier
IMHO
template< typename T >
struct X
{
enum { kIsSpecialized = false };
};
template<>
struct X< A >
{
enum { kIsSpecialized = true };
};
if you cannot touch the structs you might keep a manually updated
what do you mean by "you cannot touch the structs"?
>typelist ( a la Alexandrescu ) of the specialized types anche check if
a type is in the typelist...
what will the typelist contains?
>I can't think of any other way ( so probably there are a thousands
more ... )
--
Thanks
Barry- Hide quoted text -
- Show quoted text -
If the structs are made by someone else and you cannot insert an
enum...
you might do something like
typedef TypeListCreator< A, B, C, D >::tResult
typeListOfClassXYZSpecializations;
then you can check if a type is in there with something like
enum { kIsTypeASpecialized = ( TypeListIndexOf<
typeListOfClassXYZSpecializations, A >::kResult != 0 ) };

actually != -1, if our versions are the same here
well, the naming convention of Loki is quite different with mine

As I write
typedef LOKI_TYPELIST_2(X<int>, X<float>) SpecializedList;
BOOST_STATIC_ASSERT((Loki::TL::IndexOf<Specialized List, X<bool>
>::value) == -1);


TypeListCreator and TypeListIndexOf are typelist handling classes a la
Alexandrescu.
Obviously the list must be manually updated so it is helpful just to
keep everything in one place...
Regards,
FB

--
Thanks
Barry- Hide quoted text -

- Show quoted text -
Sorry, I don't use loki, I've been having fun doing my own type list
handlers and I've done the IndexOf class 1-based. Or maybe not... let
me go and check. Just kidding, my mistake there.
Bye,
FB

Sep 3 '07 #8

P: n/a
xt*********@gmail.com wrote:
On Sep 3, 2:13 pm, "Hendrik Schober" <SpamT...@gmx.dewrote:
>Hi,

suppose we have

template< typename T >
struct X;

and some specializations:

template<>
struct X<A{};

template<>
struct X<B{};

template<>
struct X<B{};

Given a type 'U', is there a way to find out whether the
definition 'X<U>' exists? (The result should be a compile-
time constant, so that it can be used for specializing
other templates.)

Schobi

--
SpamT...@gmx.de is never read
I'm HSchober at gmx dot de
"A patched buffer overflow doesn't mean that there's one less way attackers
can get into your system; it means that your design process was so lousy
that it permitted buffer overflows, and there are probably thousands more
lurking in your code."
Bruce Schneier

IMHO

template< typename T >
struct X
{
enum { kIsSpecialized = false };
};

template<>
struct X< A >
{
enum { kIsSpecialized = true };
};

if you cannot touch the structs you might keep a manually updated
typelist ( a la Alexandrescu ) of the specialized types anche check if
a type is in the typelist...

I can't think of any other way ( so probably there are a thousands
more ... )

I think of another way (in your "thousand more" :-) ) to do compile-time

#include <boost/static_assert.hpp>
template <class T>
struct X;

template <>
struct X<int>
{
};

template <>
struct X<float>
{
};

struct true_type
{
char dummy[256];
};

struct false_type
{
char dummy[1];
};

template <class U>
struct Traiter
{
static true_type test(X<int>);
static true_type test(X<float>);
static false_type test(...);

static X<Umake_xt();

enum { value = (sizeof(test(make_xt())) == sizeof(true_type)) };
};

int main()
{
using namespace std;
BOOST_STATIC_ASSERT(Traiter<int>::value);
BOOST_STATIC_ASSERT(Traiter<float>::value);
BOOST_STATIC_ASSERT(!Traiter<bool>::value);;
}

--
Thanks
Barry
Sep 3 '07 #9

P: n/a
"Barry" <dh*****@gmail.comwrote:
[...]
I think of another way [...]
...which doesn't help either as I have to know the set
of instances before-hand. <sigh>
I explain again and will try to be more specific.

There's a template declaration:

template< typename T >
struct X;

There are at least two specializations:

template<>
struct X<A{};

template<>
struct X<B{};

However, there might be more specializations. There might
even be a definition of the general template. Which of the
specializations are present (or whether the definition of
the primary template is present) depends on a lot of things.
Rather than starting to do massive '#if'ing in the code, I
would like to have a single piece of template code which
finds this out, so that I can use it to trigger the
instanciation of other templates.
What I need is a
template< template<class C, typename T >
struct has_instance {
enum { value = /* ... */ };
};
(where /* ... */ is the piece I don't know), so that I can
use it like this
has_instance< X, U >::value
and get a compile-time constant.
Barry
Schobi

--
Sp******@gmx.de is never read
I'm HSchober at gmx dot de
"A patched buffer overflow doesn't mean that there's one less way attackers
can get into your system; it means that your design process was so lousy
that it permitted buffer overflows, and there are probably thousands more
lurking in your code."
Bruce Schneier
Sep 3 '07 #10

P: n/a
Hendrik Schober wrote:
"Barry" <dh*****@gmail.comwrote:
>[...]
I think of another way [...]

...which doesn't help either as I have to know the set
I knew it wasn't help, so I didn't directly reply to your thread
of instances before-hand. <sigh>
I explain again and will try to be more specific.

There's a template declaration:

template< typename T >
struct X;

There are at least two specializations:

template<>
struct X<A{};

template<>
struct X<B{};

However, there might be more specializations. There might
even be a definition of the general template. Which of the
specializations are present (or whether the definition of
the primary template is present) depends on a lot of things.
Rather than starting to do massive '#if'ing in the code, I
would like to have a single piece of template code which
finds this out, so that I can use it to trigger the
instanciation of other templates.
What I need is a
template< template<class C, typename T >
struct has_instance {
enum { value = /* ... */ };
};
(where /* ... */ is the piece I don't know), so that I can
use it like this
has_instance< X, U >::value
and get a compile-time constant.
Well, IMHO, this is a little like the `has_virtual_destructor' issue,
you have to ask the compiler to give out the information, which it
really has during compile-time.
Sep 4 '07 #11

P: n/a
On 9 3 , 8 13 , "Hendrik Schober" <SpamT...@gmx.dewrote:
Hi,

suppose we have

template< typename T >
struct X;

and some specializations:

template<>
struct X<A{};

template<>
struct X<B{};

template<>
struct X<B{};

Given a type 'U', is there a way to find out whether the
definition 'X<U>' exists? (The result should be a compile-
time constant, so that it can be used for specializing
other templates.)
after revising the code I post else-thread, it seems to work as you
wish

#include <iostream>

using namespace std;

template <class T>
struct X;

template <>
struct X<int>
{
};

template <>
struct X<float>
{
};

template <class U>
struct is_specialized
{
struct true_type
{
char dummy[256];
};

struct false_type
{
char dummy[1];
};

template <class T>
static true_type test(X<T>);

static false_type test(...);

template <class T>
static X<Tmake_xt();

enum { value = (sizeof(test(make_xt<U>())) ==
sizeof(true_type)) };
};

int main()
{
cout << is_specialized<int>::value << endl;
cout << is_specialized<float>::value << endl;
cout << is_specialized<bool>::value << endl;
}

Sep 4 '07 #12

P: n/a
Barry Ding <dh*****@gmail.comwrote:
[...]
after revising the code I post else-thread, it seems to work as you
wish
[snipped code]
Thanks a lot, this indeed looks like it does! It
also works when the primary 'X' is fully defined.
When I saw you post the 'sizeof' trick I thought
this might be a way to do it, but I couldn't wrap
my head around it for long enough to come up with
something...
Thanks!

Schobi

--
Sp******@gmx.de is never read
I'm HSchober at gmx dot de
"A patched buffer overflow doesn't mean that there's one less way attackers
can get into your system; it means that your design process was so lousy
that it permitted buffer overflows, and there are probably thousands more
lurking in your code."
Bruce Schneier

Sep 4 '07 #13

P: n/a
On Sep 4, 8:36 am, Barry Ding <dhb2...@gmail.comwrote:
On 9 3 , 8 13 , "Hendrik Schober" <SpamT...@gmx.dewrote:


Hi,
suppose we have
template< typename T >
struct X;
and some specializations:
template<>
struct X<A{};
template<>
struct X<B{};
template<>
struct X<B{};
Given a type 'U', is there a way to find out whether the
definition 'X<U>' exists? (The result should be a compile-
time constant, so that it can be used for specializing
other templates.)

after revising the code I post else-thread, it seems to work as you
wish

#include <iostream>

using namespace std;

template <class T>
struct X;

template <>
struct X<int>
{

};

template <>
struct X<float>
{

};

template <class U>
struct is_specialized
{
struct true_type
{
char dummy[256];
};

struct false_type
{
char dummy[1];
};

template <class T>
static true_type test(X<T>);

static false_type test(...);

template <class T>
static X<Tmake_xt();

enum { value = (sizeof(test(make_xt<U>())) ==
sizeof(true_type)) };

};

int main()
{
cout << is_specialized<int>::value << endl;
cout << is_specialized<float>::value << endl;
cout << is_specialized<bool>::value << endl;

}- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -
Hi to all,
Sorry for continuing but I'd be very interested into this.
Anyway I tried but at least on the compiler I have access to right now
it does not work.

make_xt< T returning X< T seems to always match test( X< T ),
never test(...)
I kind of expected that but I'm usually wrong... :-(

In addition if

template< typename T >
struct X;

is not defined I get some errors saying I'm trying to use an undefined
struct...

Barry, what compiler are you using?

Sep 4 '07 #14

P: n/a
xt*********@gmail.com <xt*********@gmail.comwrote:
On Sep 4, 8:36 am, Barry Ding <dhb2...@gmail.comwrote:
[...]
after revising the code I post else-thread, it seems to work as you
wish

#include <iostream>

using namespace std;

template <class T>
struct X;

template <>
struct X<int>
{

};

template <>
struct X<float>
{

};

template <class U>
struct is_specialized
{
struct true_type
{
char dummy[256];
};

struct false_type
{
char dummy[1];
};

template <class T>
static true_type test(X<T>);

static false_type test(...);

template <class T>
static X<Tmake_xt();

enum { value = (sizeof(test(make_xt<U>())) ==
sizeof(true_type)) };

};

int main()
{
cout << is_specialized<int>::value << endl;
cout << is_specialized<float>::value << endl;
cout << is_specialized<bool>::value << endl;

}- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -

Hi to all,
Sorry for continuing but I'd be very interested into this.
Anyway I tried but at least on the compiler I have access to right now
it does not work.
It works for me using VC8. However, Comeau says:

"ComeauTest.c", line 31: error: function
"is_specialized<U>::make_xt<T>() [with U=bool, T=bool]" returns
incomplete type "X<bool>"
enum { value = (sizeof(test(make_xt<U>())) == sizeof(true_type)) };
^
detected during instantiation of class
"is_specialized<U[with U=bool]" at line 40

Too bad. :(
[...]
Schobi

--
Sp******@gmx.de is never read
I'm HSchober at gmx dot de
"A patched buffer overflow doesn't mean that there's one less way attackers
can get into your system; it means that your design process was so lousy
that it permitted buffer overflows, and there are probably thousands more
lurking in your code."
Bruce Schneier
Sep 4 '07 #15

P: n/a
xt*********@gmail.com wrote:
On Sep 4, 8:36 am, Barry Ding <dhb2...@gmail.comwrote:
>On 9 3 , 8 13 , "Hendrik Schober" <SpamT...@gmx.dewrote:


>>Hi,
suppose we have
template< typename T >
struct X;
and some specializations:
template<>
struct X<A{};
template<>
struct X<B{};
template<>
struct X<B{};
Given a type 'U', is there a way to find out whether the
definition 'X<U>' exists? (The result should be a compile-
time constant, so that it can be used for specializing
other templates.)
after revising the code I post else-thread, it seems to work as you
wish

#include <iostream>

using namespace std;

template <class T>
struct X;

template <>
struct X<int>
{

};

template <>
struct X<float>
{

};

template <class U>
struct is_specialized
{
struct true_type
{
char dummy[256];
};

struct false_type
{
char dummy[1];
};

template <class T>
static true_type test(X<T>);

static false_type test(...);

template <class T>
static X<Tmake_xt();

enum { value = (sizeof(test(make_xt<U>())) ==
sizeof(true_type)) };

};

int main()
{
cout << is_specialized<int>::value << endl;
cout << is_specialized<float>::value << endl;
cout << is_specialized<bool>::value << endl;

}- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -

Hi to all,
Sorry for continuing but I'd be very interested into this.
Anyway I tried but at least on the compiler I have access to right now
it does not work.

make_xt< T returning X< T seems to always match test( X< T ),
never test(...)
I kind of expected that but I'm usually wrong... :-(

In addition if

template< typename T >
struct X;

is not defined I get some errors saying I'm trying to use an undefined
struct...

Barry, what compiler are you using?
MSVC8 you may already guess :-)

After I post the code, I did check it with Comeau too,
So this must be another bug with MSVC8 too.
pity

--
Thanks
Barry
Sep 4 '07 #16

P: n/a
Barry <dh***@126.comwrote:
[:::]
After I post the code, I did check it with Comeau too,
So this must be another bug with MSVC8 too.
Yep. GCC barks at it, too.
pity
Schobi

--
Sp******@gmx.de is never read
I'm HSchober at gmx dot de
"A patched buffer overflow doesn't mean that there's one less way attackers
can get into your system; it means that your design process was so lousy
that it permitted buffer overflows, and there are probably thousands more
lurking in your code."
Bruce Schneier
Sep 4 '07 #17

This discussion thread is closed

Replies have been disabled for this discussion.