constexpr函数,返回模板化函数实例的地址

时间:2013-01-23 07:45:31

标签: c++ c++11 clang

考虑以下示例:

#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);
}

我用Xcode 4.5.2测试了它 - Apple clang 4.1版(标签/ Apple / clang-421.11.66)(基于LLVM 3.1svn)
我想要太多吗?

1 个答案:

答案 0 :(得分:4)

参数声明

constexpr auto wrap(Type p)

与模板名称

不兼容
template wrapper<p>

即使在constexpr函数中,参数也不能用作常量表达式。

通常这个错误表现为尝试根据参数的值调整constexpr函数的返回类型,但这是一个小的微妙,因为类型表达式是值计算的一部分,值始终具有相同的类型。

根本问题是要求模板执行运行时工作。您可以决定在运行时调用它的PTMF。

constexpr永远不会限制可能传递给函数的参数。 (即,只能使用常量参数调用函数。)它仅使函数成为在需要常量的上下文中使用的函数。