This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [c++0x] Considering better error messages for templates.


I forgot the link:

http://blog.think-async.com/

2009/12/11 Germán Diago <germandiago@gmail.com>:
> Hello. Looking at a (fantastic) blog, I came up with this and I think
> it should be useful to considerate it when implementing
> c++0x libraries. We all know that template errors are very
> frustrating. So there is a technique here which would work great.
>
>
> The C++0x features decltype, static_assert and the "new function
> declarator syntax" can be combined with our old friend SFINAE to
> generate nicer template compile errors.
>
> As a simple example, consider a container class similar to std::set.
> Normally if you just declare a variable
>
> set<my_type> s;
>
> it will compile without error even if my_type has no operator<. You
> will only get an error when you try to call a set member function,
> such as insert(). Worse still, the errors tend to be quite verbose.
> (Too verbose for me to want to paste here, anyway.) It would be really
> nice to generate a short, readable error at the point of the original
> variable declaration. Let's see how we can do just that in C++0x.
>
> First, we need to write a compile-time test for operator<. This is
> where SFINAE, decltype and the new function declarator syntax come
> together. We write the test function:
>
> auto less_than_test(const T* t)
> ?-> decltype(*t < *t, char(0));
>
> and the fallback overload:
>
> std::array<char, 2> less_than_test(...);
>
> The trick here is that, according to the C++0x grammar, we have:
>
> decltype ( expression )
>
> and
>
> expression:
> ? ?assignment-expression
> ? ?expression , assignment-expression
>
> This means that the first overload uses decltype to do two things: it
> makes the overload a viable candidate only if the expression *t < *t
> is valid; and it says the overload returns a char.
>
> Second, we can use sizeof to determine which of the overloads is
> selected for a given type T, and static_assert to generate a readable
> error:
>
> template <typename T>
> class set
> {
> public:
> ?static_assert(
> ? ? ?sizeof(less_than_test((T*)0)) == 1,
> ? ? ?"type T must provide operator<");
> };
>
> The g++ 4.4 compiler then gives the following output on the original
> variable declaration:
>
> test.cpp: In instantiation of set<my_type>
> test.cpp:21: ? instantiated from here
> test.cpp:13: error: static assertion failed:
> ? ?"type T must provide operator<"
>
> It works with function templates too.
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]