Getting CTAssert to compile

Getting CTAssert to compile

Post by Scott Meyer » Wed, 20 Sep 2000 04:00:00



Recently I've been introducing people to template metaprogramming stuff,
and one of the examples I like is showing how to ensure that a template
argument T inherits from some specific base class, e.g., Widget.  This is
the code I've been using:

  // CTAssert = "Compile Time Assertion".  By design, only CTAssert<true> is
  // defined.  Use of CTAssert<false> indicates a violated assertion.
  template<bool> class CTAssert;
  template<> class CTAssert<true> {};

  // The following asserts that shorts and longs are different sizes.  I
  // prefer this to the more theoretically iron-clad use of array types,
  // because this way I don't have to remember the syntax for functions
  // returning references to arrays.
  typedef short Yes;
  typedef long No;
  CTAssert< sizeof(Yes) != sizeof(No) > ensureDifferentSizesAssertion;

  class Widget;

  // For a type T, the version of checkType returning Yes is a better match
  // when T (publicly) inherits from Widget than is the version of checkType
  // returning No.  For all other types, checkType returning No is the better
  // match.
  Yes checkType(const Widget*);
  No  checkType(...);

  // The following class template should be instantiable only when T* is
  // implicitly convertible to Widget*.
  template<typename T>
  class Something:
    private CTAssert< sizeof(checkType(static_cast<T*>(0))) == sizeof(Yes) >
  {};

  class Widget{};
  class Foo: public Widget {};

  // This should compile, because Foo inherits from Widget.
  Something<Foo> s;

This works perfectly in my head, but it's rejected by MSVC6.4, MWCW 5.3 and
6, g++ 2.95.2, Borland C++ 5.5.1, and Comeau C++ 4.2.42.  Sigh.  Am I doing
something invalid in the code above?  If not, does anybody know of a
compiler that will accept my code?

Thanks,

Scott

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]

[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]

 
 
 

Getting CTAssert to compile

Post by Jan Dj?r » Thu, 21 Sep 2000 04:00:00



> This works perfectly in my head, but it's rejected by MSVC6.4, MWCW 5.3 and
> 6, g++ 2.95.2, Borland C++ 5.5.1, and Comeau C++ 4.2.42.  Sigh.  Am I doing
> something invalid in the code above?  If not, does anybody know of a
> compiler that will accept my code?

I had to make three changes to make it compile with Gcc 2.95:

Quote:

>   CTAssert< sizeof(Yes) != sizeof(No) > ensureDifferentSizesAssertion;

CTAssert< (bool)(sizeof(Yes) != sizeof(No)) >
ensureDifferentSizesAssertion;

Quote:>   class Something:
>     private CTAssert< sizeof(checkType(static_cast<T*>(0))) == sizeof(Yes) >
>   {};

class Something:
   private CTAssert< (bool)(sizeof(checkType((T*)(0)))) == sizeof(Yes) >
{};

Gcc 2.95.2 perhaps don't need the static_cast removed, I don't have that
version available right now.

        Jan D.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]

[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]

 
 
 

Getting CTAssert to compile

Post by Brian McNamar » Sun, 24 Sep 2000 04:00:00



Quote:>  CTAssert< sizeof(Yes) != sizeof(No) > ensureDifferentSizesAssertion;
...
>    private CTAssert< sizeof(checkType(static_cast<T*>(0))) == sizeof(Yes) >
...
>This works perfectly in my head, but it's rejected by MSVC6.4, MWCW 5.3 and
>6, g++ 2.95.2, Borland C++ 5.5.1, and Comeau C++ 4.2.42.  Sigh.  Am I doing
>something invalid in the code above?  If not, does anybody know of a
>compiler that will accept my code?

I am pretty sure your code is valid (I spent a few minutes paging
through the standard), and thus to all the compiler-implementers in the
audience, you've made your point.  :)

Nevertheless, I feel compelled to mention that, as a practical matter,
if you _parenthesize_ constant expressions that are used a non-type
template arguments, then this helps many compilers parse it.

For example, when I changed the first code above to this:

   CTAssert<( sizeof(Yes) != sizeof(No) )> ensureDifferentSizesAssertion;
            ^                           ^
g++ parsed it happily, and when I did it to here:

   private CTAssert<( sizeof(checkType(static_cast<T*>(0))) == sizeof(Yes) )>
                    ^                                                      ^
then g++ did still die, but gracefully, with a "sorry, not implemented"
message.

Slightly more heavyweight, and not quite as usable: if you assign such
expressions to constants, this seems to help a lot.  In other words,
change

   foo< some_const_exp > some_var;

to

   static const int x = some_const_exp;
   foo<x> some_var;

and this makes some compilers (g++, at least) happy in almost all cases.

--
Brian McNamara

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]

[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]

 
 
 

1. help getting TAPI samples from sells site to compile

Hello,  

I recently picked up Chris Sells book on TAPI and downloaded the
sample TAPI programs at www.sellbrothers.com/telprog.

Has anyone experienced problems getting the sample TAPI programs to
link?  I was able to get them to compile but when they try and link i
get lots of LNK2001 errors.

I am running VC++ 6.0 and  have the tfx20 libs compiled and are in the
project settings.  But still no luck..

Can anyone help?

Thanks,
Ryan


2. Attention planners and budgeteers: new documentation available.

3. Help: Has anyone gotten the ODBC 1.0 samples compiled under BCC 4.0?

4. Is portmapping (PAT) possible with w2k routing?

5. Getting the language to compile on an sgi

6. Can't run MS Word 6.0

7. Displaying compiling switches while compiling in IDE

8. NT server migration-please help

9. Possible to use Borland-compiled DLL with MSVC++ compiled main program??

10. (VC++) Build->Compile does not compile

11. Compiling a compiler with a compiled compiler

12. does not compile in gcc2.95.2-1 but will compile with borland 5.01

13. How to make the following compile in HP compile?