core: Report useful error message if function pointer is passed

The value constructor generates a useful error message if the client code
passes a pointer to something that isn't void. Unfortunately, the compiler
doesn't get that far if a function pointer is passed because the
value(T *p) forwarding constructor ends up trying to call itself which
results in an error like:

 .../fmt/core.h:485:34: error: constructor delegates to itself
    value(T *p) : value(as_const(p)) {}

So, let's add an extra constructor that is a better match for function
pointers so that a similar useful error message can be emitted. We need to
force the compiler to decide whether to generate the message only when
something would actually cause the constructor to be called by making the
static_assert expression use the template parameter.
This commit is contained in:
Mike Crowe 2017-12-28 19:45:08 +00:00
parent 6f2769d0b4
commit 53cae289b7

View File

@ -468,6 +468,18 @@ class value {
set<POINTER>(pointer, p);
}
// Match function pointers explicitly. If we do not then the
// forwarding T * constructor below will end up trying to call
// itself when a function pointer is passed, which leads to a
// confusing error message.
template <typename T, typename ...Args>
value(T (*p)(Args...)) {
// This static_assert must use something that is dependent on T,
// otherwise it will always fire, so let's use the same check as
// above - it will never match.
static_assert(std::is_same<T, void>::value, "formatting of function pointers is disallowed");
}
template <typename T>
value(T *p) : value(as_const(p)) {}