On 09/25/2017 02:03 AM, Martin Sebor wrote:
> +a @option{-Wincompatible-pointer-types} warning for mismatches. To suppress
> +a warning for the necessary cast from a pointer to the implementation member
> +function to the type of the corresponding non-member function use the
> +@option{-Wno-pmf-conversions} option. For example:
FWIW, it seems odd to me to tell users they need to suppress warnings, when
the compiler surely could provide better/safer means to avoid needing
to use the reinterpret_cast hammer. See below.
> +
> +@smallexample
> +class S
> +@{
> +private:
> + int debug_impl (int);
> + int optimized_impl (int);
> +
> + typedef int Func (S*, int);
> +
> + static Func* resolver ();
> +public:
> +
> + int interface (int);
> +@};
> +
> +int S::debug_impl (int) @{ /* @r{@dots{}} */ @}
> +int S::optimized_impl (int) @{ /* @r{@dots{}} */ @}
> +
> +S::Func* S::resolver ()
> +@{
> + int (S::*pimpl) (int)
> + = getenv ("DEBUG") ? &S::debug_impl : &S::optimized_impl;
> +
> + // Cast triggers -Wno-pmf-conversions.
> + return reinterpret_cast<Func*>(pimpl);
> +@}
> +
If I were writing code like this, I'd write a reinterpret_cast-like
function specifically for pointer-to-member-function to free-function
casting, and only suppress the warning there instead of disabling
the warning for the whole translation unit. Something like:
#include <type_traits>
template<typename T> struct pmf_as_func;
template<typename Ret, typename S, typename... Args>
struct pmf_as_func<Ret (S::*) (Args...)>
{
typedef Ret (func_type) (S *, Args...);
typedef S struct_type;
};
template<typename Pmf>
typename pmf_as_func<Pmf>::func_type *
pmf_as_func_cast (Pmf pmf)
{
static_assert (!std::is_polymorphic<typename
pmf_as_func<Pmf>::struct_type>::value,
"");
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpmf-conversions"
return reinterpret_cast<typename pmf_as_func<Pmf>::func_type *> (pmf);
#pragma GCC diagnostic pop
}
and then write:
return pmf_as_func_cast (pimpl);
instead of:
return reinterpret_cast<Func*>(pimpl);
The point being of course to make it harder to misuse the casts.
But that may be a bit too much for the manual.
It also wouldn't work as is with C++03 (because variatic templates).
Which leads me to think that if GCC guarantees this cast works, then
it'd be nice to have GCC provide it (like a __pmf_as_func_cast function)
as builtin. Then it'd work on C++03 as well, and the compiler of course
can precisely validate whether the cast is valid. (It's quite possible
that there's a better check than is_polymorphic as I've written above.)
Just a passing thought.
Thanks,
Pedro Alves