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

  • Thread starter Hendrik Schober
  • Start date
H

Hendrik Schober

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

--
(e-mail address removed) 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
 
X

xtrigger303

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

--
(e-mail address removed) 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 ... )
 
B

Barry

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?
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

what do you mean by "you cannot touch the structs"?

If you can't change the code containing the specialisations.
what will the typelist contains?

Once of each of the specialisations, in other words it should be a list
of all the specialisations.
 
X

xtrigger303

what do you mean by "you cannot touch the structs"?


what will the typelist contains?


--
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
 
H

Hendrik Schober

Erik Wikström said:
On Sep 3, 2:13 pm, "Hendrik Schober" <[email protected]> wrote:
[...]
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.
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

--
(e-mail address removed) 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
 
B

Barry

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
 
X

xtrigger303

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

As I write




--
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
 
B

Barry

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<U> make_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);;
}
 
H

Hendrik Schober

Barry said:
[...]
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

Schobi

--
(e-mail address removed) 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
 
B

Barry

Hendrik said:
Barry said:
[...]
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.
 
B

Barry Ding

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<T> make_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;
}
 
H

Hendrik Schober

Barry Ding said:
[...]
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

--
(e-mail address removed) 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
 
X

xtrigger303

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<T> make_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?
 
H

Hendrik Schober

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<T> make_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

--
(e-mail address removed) 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
 
B

Barry

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<T> make_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
 
H

Hendrik Schober

Barry said:
[:::]
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.

Schobi

--
(e-mail address removed) 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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top