Board index » cppbuilder » Template-Meta: Finding out whether a template-definition exists

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


2007-09-04 09:08:16 PM
cppbuilder33
Hi,
I already asked this over in c.l.c++, but had no luck, so
I thought I'd try here next.
I need to find out at compile-time whether a specific
instance of some template is defined.
Consider this:
template< typename T>struct X; // declaration only
template<>struct X<A>{}; // definition
template<>struct X<B>{}; // another definition
However, there might be more specializations. There might
even be a definition of the primary 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.
So 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 that says whether 'X<U>'
is defined or not.
Is there a way to do this?
Schobi
--
XXXX@XXXXX.COM 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
 
 

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

"Hendrik Schober" < XXXX@XXXXX.COM >writes:
Quote
So 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 that says whether 'X<U>'
is defined or not.

Is there a way to do this?
I don't think it's possible. I don't see how the answer could found
without already having compiled all the files in the project!
However, if the code makes use of your hypothetical has_instance<>
template, it can't compile the files in the project without already
knowing the answer.
Another bigger problem with "has_instance" is the possible violation
of the one definition rule. Since compilers are not clairvoyant, and
only operate on information that they currently know, if you did have
a "has_instance<>" template, the instantiation of THAT template would
change depending on the file currently being compiled. It could
return true in one .cpp file, but false in all others. That would be
bad.
--
Chris (TeamB);
 

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

Chris Uzdavinis (TeamB) < XXXX@XXXXX.COM >wrote:
Quote
"Hendrik Schober" < XXXX@XXXXX.COM >writes:

>So 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 that says whether 'X<U>'
>is defined or not.
>
>Is there a way to do this?


I don't think it's possible. I don't see how the answer could found
without already having compiled all the files in the project! [...]
I don't understand this.
I want to know hether, at the point of instanciation
of 'has_instance', some template instance is defined,
not, whether it's defined /somewhere/ in the project.
Quote
Another bigger problem with "has_instance" is the possible violation
of the one definition rule. Since compilers are not clairvoyant, and
only operate on information that they currently know, if you did have
a "has_instance<>" template, the instantiation of THAT template would
change depending on the file currently being compiled. It could
return true in one .cpp file, but false in all others. That would be
bad.
Mhmm. I need to think about this...
Schobi
--
XXXX@XXXXX.COM 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
 

{smallsort}

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

Were there to be a static array and a static function then each
instantiation of a template could in the constructor search the array for an
indicator of the type, increment the count or if not found, add that to the
array. Calling the static function would then return true/false on if an
instance of that specialization of the template existed.
That is a lot of work to implement and most probably requires a helper class
into which one can bury the work.
Better to try to figure out another way to do what you want instead of
looking for an instance of a certain specialization.
. Ed
Quote
Hendrik Schober wrote in message
news: XXXX@XXXXX.COM ...

I already asked this over in c.l.c++, but had no luck, so
I thought I'd try here next.

I need to find out at compile-time whether a specific
instance of some template is defined.
Consider this:

template< typename T>struct X; // declaration only

template<>struct X<A>{}; // definition

template<>struct X<B>{}; // another definition

However, there might be more specializations. There might
even be a definition of the primary 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.

So 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 that says whether 'X<U>'
is defined or not.

Is there a way to do this?
 

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

"Hendrik Schober" < XXXX@XXXXX.COM >wrote in message
Quote
I need to find out at compile-time whether a specific
instance of some template is defined.
[...]
Quote
Is there a way to do this?
SFINAE?
if I undefstand you correctly you want to find out if class is defined
(it does not matter that class is a template)
class A;
class B;
template< typename T>struct X;
template<>struct X<A>{};
template<class T>
struct if_defined
{
template <class U>static char (&f(char(*)[sizeof(U)]))[2];
template <class U>static char (&f(...))[1];
enum { result =sizeof( f<T>( 0 ) )-1 };
};
int main()
{
bool a[ if_defined< X<A>>::result ];
bool b[ if_defined< X<B>>::result ];
}
unfortunately I could not make it work with either BDS2006
(internal compiler error) or VS2005 (use of undefined type),
but with comey online it seems working. It compiles and gives
only one error
"ComeauTest.c", line 19: error: the size of an array must be greater than
zero
bool b[ if_defined< X<B>>::result ];
which means that if_defined< X<A>>::result is a nonzero value,
and if_defined< X<B>>::result is zero
Cheers,
Serge
 

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

"Sergiy Kanilo" < XXXX@XXXXX.COM >writes:
Quote
SFINAE?
if I undefstand you correctly you want to find out if class is defined
(it does not matter that class is a template)
Well...
Quote
bool a[ if_defined< X<A>>::result ];
If it's not defined this code doesn't compile. That's your intent,
but if it did compile, you would have the issue when
if_defined < X<A>>::result=1 // in file1.cpp
if_defined < X<A>>::result=0 // in file2.cpp
That violates the one definition rule, is not required to be reported,
and has undefined behavior.
--
Chris (TeamB);
 

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

Sergiy Kanilo wrote:
Quote

unfortunately I could not make it work with either BDS2006
Serge, could you explain how exactly does this code work? Why are the
template methods needed? And how exactly does the resolution work?
Thanks,
Alex
p.s. I think the ICE will be gone in the next version of BCB.
 

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

"Chris Uzdavinis (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote
"Sergiy Kanilo" < XXXX@XXXXX.COM >writes:
but if it did compile, you would have the issue when

if_defined < X<A>>::result=1 // in file1.cpp
if_defined < X<A>>::result=0 // in file2.cpp

That violates the one definition rule, is not required to be reported,
and has undefined behavior.
IMHO it is not a problem with different cpp - just wrap the template
in namespace {}.
More complex situation is when an uncompleted name becomes
complete within one compilation unit and you have to ensure that you
never apply the template to the same class name twice.
To do that you can add an extra integral parameter and supply a new
number every time you use the template. You probably need some tool
to do that, but in simple cases it could be done manually.
Cheers,
Serge
 

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

Quote
p.s. I think the ICE will be gone in the next version of BCB.
What is "ICE" ?
. Ed
Quote
Alex Bakaev wrote in message
news:46dd9c0b$ XXXX@XXXXX.COM ...
 

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

"Ed Mulroy [TeamB]" < XXXX@XXXXX.COM >writes:
Quote
>p.s. I think the ICE will be gone in the next version of BCB.

What is "ICE" ?
Internal Compiler Error.
--
Chris (TeamB);
 

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

"Alex Bakaev [TeamB]" < XXXX@XXXXX.COM >wrote in message
Quote
Sergiy Kanilo wrote:
>unfortunately I could not make it work with either BDS2006

Serge, could you explain how exactly does this code work? Why are the
template methods needed? And how exactly does the resolution work?
after second thought, it probably should not
The SFINAE does not work if I trying to evaluate an invalid expression,
and sizeof(A) is an invalid expression if A is not defined
Cheers,
Serge
 

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

Sergiy Kanilo wrote:
Quote

after second thought, it probably should not

Too bad :)
 

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

Ok.
I always thought of ICE as In Circuit Emulator and wondered what Alex was
talking about.
. Ed
Quote
Chris Uzdavinis wrote in message
news: XXXX@XXXXX.COM ...

>What is "ICE" ?

Internal Compiler Error.
 

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

Ed Mulroy [TeamB] wrote:
Quote
Ok.

I always thought of ICE as In Circuit Emulator and wondered what Alex was
talking about.

As a C++ programmer you should be familiar with the concept of
overloading ;)
 

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

Overloading and Internal Compiler Error are not necessarily related.
. Ed
Quote
Alex Bakaev wrote in message
news: XXXX@XXXXX.COM ...

As a C++ programmer you should be familiar with the concept of overloading
;)