TITLE: constraining template regarding built-in types (Newsgroups: comp.lang.c++.moderated, 6 Jun 97) BUCKLEY: Brian K. Buckley (bbuckley@tiac.net) : template class X{ : // ... : void constraints(T* tp){ : T* tp; : B* bp = tp; // works if T is a B : }; : }; : : The above example from D&E C++ is a way of constraining template arguments : to only classes which are derived from B. : : Is there a comparable technique to constrain template arguments to only : classes NOT derived from B? KUEHL: kuehl@horn.informatik.uni-konstanz.de (Dietmar Kuehl) You can easily do it both ways. However, to determine whether a type is built-in you need soe definitions. Here is an example: struct cat_base { struct b_in {}; struct u_def {}; }; template struct cat: cat_base { static u_def builtin() { return u_def(); } }; struct cat:cat_base { static b_in builtin() { return b_in(); }}; struct cat:cat_base { static b_in builtin() { return b_in(); }}; struct cat:cat_base { static b_in builtin() { return b_in(); }}; struct cat:cat_base { static b_in builtin() { return b_in(); }}; struct cat:cat_base { static b_in builtin() { return b_in(); }}; struct cat:cat_base { static b_in builtin() { return b_in(); }}; struct cat:cat_base{ static b_in builtin() { return b_in(); }}; struct cat:cat_base { static b_in builtin() { return b_in(); }}; struct cat:cat_base { static b_in builtin() { return b_in(); }}; struct cat:cat_base { static b_in builtin() { return b_in(); }}; struct cat:cat_base { static b_in builtin() { return b_in(); }}; struct cat:cat_base { static b_in builtin() { return b_in(); }}; struct cat:cat_base { static b_in builtin() { return b_in(); }}; struct cat:cat_base { static b_in builtin() { return b_in(); }}; template void foo(T const &) { cat_base::u_def dummy = cat::builtin(); } struct bar {}; int main() { foo(bar()); // OK foo(int()); // Error return 0; } This uses full specialization to determine the category of a type: it is either classified as being built-in or as user defined. There can, of course, also be more classes, if this would be useful. To make sure that the compilation fails, you can use an assignment in an instantiated function. For a function template it obvious that you can just put it in. For a class template, it more difficult: members not used are not checked for correctness. Thus, you need to place the constraint test into a function which is actually used. If you use objects of the corresponding class, the destructor is an obvious place. For classes not really instantiated, it is more complex and I don't know off-hand of a general approach working there, too.