将函数绑定到类型的更好语法?

时间:2013-02-25 00:44:28

标签: c++ templates c++11

我正在尝试将函数绑定到类型中 - 请考虑以下测试程序:

#include <utility>

template <class Ret, class Arg>
struct func {
    typedef Ret (&ref)(Arg);
    template <ref Fn>
    struct bind {
        template <class NewArg>
        Ret operator()(NewArg&& arg) {
            return Fn(std::forward<Arg>(arg));
        }
    };
};

int foo(int i) {
    return i;
}

typedef func<int, int>::bind<foo> Foo;

int main(int argc, char** argv) {
    Foo foo_obj;
    return foo_obj(argc);
}

这很有效,但我个人认为func<int, int>::bind<foo>很丑,而且它也是多余的 - 但我似乎无法做func::bind<foo>并且从模板参数中推断出Ret和Arg来绑定(或者道德等同的)。我会做这样的事情:

template <class Ret, class Arg>
constexpr auto bind_func(typename func<Ret, Arg>::ref f) -> typename func<Ret, Arg>::bind<f> {
    return {};
}

但是,因为f不能保证是一个常量表达式,所以无法编译,因为编译器无法知道f是一个有效的模板参数。

有没有办法在没有持续冗余的情况下实现这一目标?

1 个答案:

答案 0 :(得分:1)

如果您可以接受宏,这可能是一个解决方案:

#include <utility>

template <class Ret, class Arg>
struct func {
    typedef Ret (&ref)(Arg);
    template <ref Fn>
    struct bind {
        template <class NewArg>
        Ret operator()(NewArg&& arg) {
            return Fn(std::forward<Arg>(arg));
        }
    };
};

template<typename T>
struct traits { };

template<typename R, typename A>
struct traits<R(A)>
{
    typedef R return_type;
    typedef A arg_type;
};

int foo(int i) {
    return i;
}

#define TYPE_WRAP(f) \
    func< \
        traits<decltype(f)>::return_type, \
        traits<decltype(f)>::arg_type \
        >::bind<f>

int main(int argc, char** argv) {
    TYPE_WRAP(foo) foo_obj;
    return foo_obj(argc);
}