C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

compiletime template check

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Serve La
Guest





PostPosted: Sat Aug 30, 2003 11:24 pm    Post subject: compiletime template check Reply with quote



I want to create a template that will stop compiling if two arrays are not
the same size, but I don't know how

This works, but I can't let the compiler stop, does anybody know how?

template<bool B> struct equalsize { enum { OK=B }; };

int main() {

int x[5]; int y[6];


if (equalsize <sizeof x == sizeof y>::OK) cout << "ok"; // expands to if
(1) or if(0)

else cout << "not ok";

return 0;

}



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Adnan
Guest





PostPosted: Sun Aug 31, 2003 8:13 am    Post subject: Re: compiletime template check Reply with quote



You're asking about compiler time assertions. I see by your writing style
that you're another Modern CPP Design fan. Smile If you've read the book than
Andrei describes in the second chapter how to use compile time assertions.
You should just declare you class empty and then specialize it for true.
Here's how you would do it.

template<bool> struct equalsize; // empty definition
template<> struct equalsize<true> { enum { OK = 1 }; }; // specializtion
for true

Now if you run your program it will fail on false condition because there's
not definition of the class given for that.



Adnan Habib.

Quote:
This works, but I can't let the compiler stop, does anybody know how?

template<bool B> struct equalsize { enum { OK=B }; };

int main() {

int x[5]; int y[6];


if (equalsize <sizeof x == sizeof y>::OK) cout << "ok"; // expands to
if
(1) or if(0)

else cout << "not ok";

return 0;

}



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ivan Vecerina
Guest





PostPosted: Sun Aug 31, 2003 12:18 pm    Post subject: Re: compiletime template check Reply with quote



"Serve La" <ik (AT) hier (DOT) nl> wrote

Quote:
I want to create a template that will stop compiling if two arrays are not
the same size, but I don't know how

This works, but I can't let the compiler stop, does anybody know how?

One simple idea is to generate an expression which becomes illegal
for some compiler-generated values.
An example is to use an array:
char myTest[ (isOk) ? 1 : -1 ]; // neg. array size -> compile error
So you could write:
char myTest[ (sizeof(x)==sizeof(y)) ? 1 : -1 ];

This can typically be wrapped in a macro, with some additional
trickery to ensure that the it can be used anywhere...

#define COMPILE_CHECK_helper2(a,b) a##b
#define COMPILE_CHECK_helper(b) COMPILE_CHECK_helper2(compile_assert_,b)
#define COMPILE_CHECK(test) struct COMPILE_CHECK_helper(__LINE__)
{ char a[(test)?1:-1], b; }


But if you prefer to avoid macros, and based on your example:
Quote:
template<bool B> struct equalsize { enum { OK=B }; };
You could write:


template<bool B> struct compile_time_check
{ enum { OK=true }; };

template<> struct compile_time_check<false> {};

int main()
{
int x[5]; int y[6];
compile_time_check< sizeof(x)==sizeof(y) >::OK;
}


There are several possible approaches. The challenge is to
get an informative non-cryptic error message upon failure,
and to avoid any diagnostic when all is ok.
(the above example may trigger a warning about the result
of the expression not being used).
So the solution may have to be tuned for each platform.


Note also that the boost library provides a (macro-based)
solution:

#include <boost/static_assert.hpp>

BOOST_STATIC_ASSERT( sizeof(x)==sizeof(y) );


hth,
Ivan
--
http://www.post1.com/~ivec



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Carl Barron
Guest





PostPosted: Sun Aug 31, 2003 1:25 pm    Post subject: Re: compiletime template check Reply with quote

Serve La <ik (AT) hier (DOT) nl> wrote:

Quote:
I want to create a template that will stop compiling if two arrays are not
the same size, but I don't know how

This works, but I can't let the compiler stop, does anybody know how?

template<bool B> struct equalsize { enum { OK=B }; };

Almost ...


first define equalize as an empty struct
template <bool B> struct equalize{};
now specialize this for the true condition
template <> struct equalize<true> {enum {OK=1};};
this should produce a compiler error as equalize<false>::OK is not
defined.

Quote:
int main() {

int x[5]; int y[6];


if (equalsize <sizeof x == sizeof y>::OK) cout << "ok"; // expands to if
(1) or if(0)

else cout << "not ok";

return 0;

}


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Richard Corden
Guest





PostPosted: Mon Sep 01, 2003 7:02 pm    Post subject: Re: compiletime template check Reply with quote

"Serve La" <ik (AT) hier (DOT) nl> writes:

Quote:
I want to create a template that will stop compiling if two arrays are not
the same size, but I don't know how

This works, but I can't let the compiler stop, does anybody know how?

template<bool B> struct equalsize { enum { OK=B }; };

int main() {

int x[5]; int y[6];


if (equalsize <sizeof x == sizeof y>::OK) cout << "ok"; // expands to if
(1) or if(0)

else cout << "not ok";

return 0;

}


The problem with sizeof for this kind of example is that two different
multi-dimension arrays could have the same size:

sizeof (int[2][5]) == sizeof (int[5][2])


The approach I think that the boost libraries take is to use a type
with two template arguments, and to partially specialize the type
where the two types are the same:


template struct are_types_equal
{
static const bool value = false;
};

template <typename T>
struct are_types_equal <T, T>
{
static const bool value = true;
};



template <bool b>
struct check_type;

template <>
struct check_type <true>
{
};



void foo ()
{
check_type < are_types_equal< int[5][2], int[5][2] > :: value > a1; // a1 Ok,
the types are the same
check_type < are_types_equal< int[5][2], int[2][5] > :: value > a2; // a2
incomplete, the types are different
}


Cheers,

Richard

--
Richard Corden
To reply remove 's' from address

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.