 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Serve La Guest
|
Posted: Sat Aug 30, 2003 11:24 pm Post subject: compiletime template check |
|
|
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
|
Posted: Sun Aug 31, 2003 8:13 am Post subject: Re: compiletime template check |
|
|
You're asking about compiler time assertions. I see by your writing style
that you're another Modern CPP Design fan. 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
|
Posted: Sun Aug 31, 2003 12:18 pm Post subject: Re: compiletime template check |
|
|
"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
|
Posted: Sun Aug 31, 2003 1:25 pm Post subject: Re: compiletime template check |
|
|
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
|
Posted: Mon Sep 01, 2003 7:02 pm Post subject: Re: compiletime template check |
|
|
"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 |
|
 |
|
|
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
|
|