Boost logo

Boost :

Subject: Re: [boost] TMP error messages [ was Re: New libraries implementing C++11 features in C++03 ]
From: Joel de Guzman (joel_at_[hidden])
Date: 2011-11-28 19:05:12

On 11/26/2011 9:22 PM, Ábel Sinkovics wrote:
> Hi,
>> The problem is that errors point to code that is deep within the library's
>> implementation, or worse, the implementations of helper libraries used
>> by the library. To understand the error, the user has to look at the
>> library's implementation. The user shouldn't have to do that -
>> understanding the implementation of a library should not be a
>> prerequisite for using it.
>> If you have any specific suggestions about what compilers could do to turn
>> these errors from deep within the library implementation, into errors
>> that do not require knowing anything about the library implementation,
>> I would like to hear it, and I'm sure so would compiler writers.
>> Otherwise, you have to accept that library writers face a trade-off
>> between the user-friendliness of error messages, and the expressiveness,
>> terseness, and power obtained by extensive use of advanced techniques
>> such as template metaprogramming. There is no one right answer to
>> this tradeoff, and it is good for users to have different alternatives
>> available to them.
> We've been experimenting with returning error messages from TMP libraries that make sense
> in the domain of the library. Our approach is returning a class describing the error when
> a metafunction is called with invalid arguments (a pretty-printer can display that
> information later in a human-readable way). The assumption is that this error information
> is returned by a metafunction deeply inside the TMP library and need to be propagated out
> (maybe changed a bit along the way to make more sense to the user). For this we've used
> monads, using which we could simulate exceptions being thrown at compile-time. Using
> monads increases the complexity of the TMP library, however, most of it can be hidden by
> another library. We've been working on such a library (not in Boost).
> What TMP library authors can do is wrapping the body of every metafunction with a template
> that "adds" error propagation to it. For example instead of:
> template <class A, class B, class C>
> struct some_metafunction_in_the_library :
> f<g<A, C>, h<B>, A>
> {};
> one can write
> template <class A, class B, class C>
> struct some_metafunction_in_the_library :
> try_<f<g<A, C>, h<B>, A> >
> {};
> in which case if f, g or h returns an error, the same error is returned by
> some_metafunction_in_the_library instead of breaking the compilation with a cryptic error
> message. At the top level it can be pretty-printed by a test harness (eg. simple binary
> built to pretty-print it or by a TMP unit testing framework). A downside of using it is
> that it makes compilation slower (see
> for measurements).
> So far we've only been using it for improving error messages coming from template
> metafunctions. Cases where they can't be easily and clearly separated from runtime code
> haven't been addressed yet.
> This solution is part of a library implementing monads in C++ template metaprogramming.
> Documentation:
> Source code:
> Note that there are only a few examples so far.

I've been reading the docs. This is very clever! I wonder how it
applies to expression templates with runtime code or Fusion with
runtime components?

A simple example would be a template plus function:

  template <typename A, typename B>
  auto plus(A const& a, B const& b) -> decltype(a+b)
  {return a+b;}

The typical problem is an error if a+b is not allowed (e.g.
a is an int but b is a std::vector). I don't see how your
solution will help more than static_assert or better yet,
Boost concepts.


Joel de Guzman

Boost list run by bdawes at, gregod at, cpdaniel at, john at