Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何创建函数模板签名?_C++_Templates_Boost - Fatal编程技术网

C++ 如何创建函数模板签名?

C++ 如何创建函数模板签名?,c++,templates,boost,C++,Templates,Boost,我有这样的模板功能: template<class R> list<R> f(const boost::function<R()>&); template<class R, class A0> list<R> f(const boost::function<R(T0)>&, list<A0>); template<class R, class A0, class A1> list<

我有这样的模板功能:

template<class R> list<R> f(const boost::function<R()>&);
template<class R, class A0> list<R> f(const boost::function<R(T0)>&, list<A0>);
template<class R, class A0, class A1> list<R> f(const boost::function<R(T0)>&, list<A0>, list<A1>);

我听说这可以通过某种模板签名专门化实现,但我不知道如何实现。

如果没有C++11,您就无法避免指定函数的返回类型

template<typename R, typename F>
    R bar(F func) {
        return func();
    }

bar<int>(foo);
如果需要实际使用函数或绑定,可以将其传递到同一接口

// without specifying the function
f(boost::bind(zero));
f(boost::bind(one, _1), 1);
f(boost::bind(two, _1, _2), 1, 2);

// or by specifying the object
boost::function<void()> f0        = boost::bind(zero);
boost::function<void(int)> f1     = boost::bind(one, _1);
boost::function<void(int,int)> f2 = boost::bind(two, _1, _2);
f(f0);
f(f1, 1);
f(f2, 1, 2);
它不必检查传递给它的内容的类型,只需检查它满足接口即可。这是C++模板通常比其他语言中的泛型强大得多的原因之一。 为了完整性。。。如果您确实想将其限制为boost::function,下面是一个示例

template<typename T>
    void p(const boost::function<T> &func) {
        func();
    }

template<typename T, typename A0>
    void p(const boost::function<T> &func, A0 a0) {
        func(a0);
    }


boost::function<void()> f0(zero);
p(f0);

boost::function<void(int)> f1(one, _1);
p(f1, 1);
如果您完全指定了函数指针,那么它就会工作,尽管这不是任何人想要做的


使用boost::bind作为证据,您应该能够根据
f
的调用约定确定arity。如果我今天有时间,我会玩它。

也许你不应该使用
boost::function
而是函数声明作为模板参数,这样你的编译器就可以从参数中知道你想要做什么:
template list f(f,list)
无论如何,我没有测试过,我确信它不会那么容易工作。谢谢,这对我帮助很大,但我还有一个问题。有没有可能像使用
zero
one
two
函数那样,但当所有这些函数都有相同的名称但参数不同时,可以这样做?@vintitres添加了更多的信息,尽管在原始指针方面不完整。我通过创建额外的模板专门化来解决这个问题:
void f(void(*func)())
模板void f(void(*func)(T0),T0 T0)
模板void f(void(*func)(T0,T1),T0 T0,T1 T1)
。也许这不干净,但有效。我相信boost::bind也有同样的功能,但我不确定。再次感谢你的回答,我的回答很清楚。
template<typename F>
    auto baz(F func) -> decltype(func()) {
        return func();
    }

baz(foo);
void zero() {cout << "zero" << endl;}
void one(int a) {cout << "one" << endl;}
void two(int a, int b) {cout << "two" << endl;}

template<typename F>
    void f(const F &func) {
        func();
    }

template<typename F, typename T0>
    void f(const F &func, T0 t0) {
        func(t0);
    }

template<typename F, typename T0, typename T1>
    void f(const F &func, T0 t0, T1 t1) {
        func(t0, t1);
    }
f(zero);
f(one, 1);
f(two, 1, 2);
// without specifying the function
f(boost::bind(zero));
f(boost::bind(one, _1), 1);
f(boost::bind(two, _1, _2), 1, 2);

// or by specifying the object
boost::function<void()> f0        = boost::bind(zero);
boost::function<void(int)> f1     = boost::bind(one, _1);
boost::function<void(int,int)> f2 = boost::bind(two, _1, _2);
f(f0);
f(f1, 1);
f(f2, 1, 2);
struct zoobies {
    void operator()() const {}
};

f(zoobies());
template<typename T>
    void p(const boost::function<T> &func) {
        func();
    }

template<typename T, typename A0>
    void p(const boost::function<T> &func, A0 a0) {
        func(a0);
    }


boost::function<void()> f0(zero);
p(f0);

boost::function<void(int)> f1(one, _1);
p(f1, 1);
void foo() {cout << "zero" << endl;}
void foo(int a) {cout << "one" << endl;}
void foo(int a, int b) {cout << "two" << endl;}
f( (void(*)())        foo      );
f( (void(*)(int))     foo, 1   );
f( (void(*)(int,int)) foo, 1, 2);