Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

constexpr function that returns address of the templated function instance

Tags:

c++

c++11

clang

Consider the following example:

#include <utility>
#include <iostream>

struct bar
{
    void baz() { std::cout << "bar::baz" << std::endl; }
};

template <typename Signature>
struct function_traits;

template <typename ReturnType, typename Class, typename ...ArgumentTypes>
struct function_traits<ReturnType (Class::*)(ArgumentTypes...)>
{
    typedef ReturnType (Class::*Signature)(ArgumentTypes...);
    typedef ReturnType (*FuncPtr)(void const *ip, ArgumentTypes&& ...);

    template <Signature mf>
    static ReturnType wrapper(void const *p, ArgumentTypes&& ...args)
    {
        Class* instance = const_cast<Class*>(static_cast<Class const *>(p));
        return (instance->*mf)(std::forward<ArgumentTypes>(args)...);
    }
};

template <typename Type>
constexpr auto wrap(Type p) -> typename function_traits<Type>::FuncPtr
{
    return &(function_traits<Type>::template wrapper<p>); // ERROR: Address of overloaded function 'wrapper' does not match required type 'void (const void *)'
}

int main()
{
    auto v = wrap(&bar::baz);
}

I've tested it with Xcode 4.5.2 - Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)
Do I want too much?

like image 669
arabesc Avatar asked Jun 21 '26 22:06

arabesc


1 Answers

The parameter declaration

constexpr auto wrap(Type p)

is incompatible with the template-name

template wrapper<p>

Even in a constexpr function, a parameter cannot be used as a constant expression.

Usually this error manifests itself as an attempt to adjust the constexpr function's return type according to the value of the argument, but this is a little subtler since the type expression is part of the value computation, with the value always having the same type.

The fundamental problem is that the template is being asked to do runtime work. You can decide what PTMF to call it with at runtime.

constexpr never restricts the arguments that may be passed to a function. (I.e., that a function may only be called with constant arguments.) It only makes the function a candidate for use in contexts where a constant is required.

like image 57
Potatoswatter Avatar answered Jun 24 '26 13:06

Potatoswatter



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!