如何摆脱绑定表达式中的冗余类型说明符

时间:2011-08-17 12:29:24

标签: c++ templates bind

请考虑以下代码:

struct f{
    void get(int a) {}
};
struct g1{
    template <typename Arg>
    void get(Arg a) {}
};
struct g2{
    template <typename... Args>
    void get(Args... args) {}
};

int f2()
{
    std::bind(&f::get,f(),2); // (A)
    std::bind(&g1::get<int>,g1(),2); // (B) redundant type specifier !
    //std::bind(&g1::get,g1(),2); // compiler error !
    std::bind(&g2::get<int, double>,g2(),2,1.1); // (C) redundant type specifiers !
    //std::bind(&g2::get,g2(),2,1.1); // compiler error !
    return 0;
}

在(B)和(C)的情况下是否可以摆脱冗余模板参数? 我希望std :: bind能自动从其参数中扣除类型。

我在考虑编写一个包含可变参数模板参数的包装器并使用 decltype可能隐藏这种冗余类型规范。

注意:我使用的是gcc 4.4

2 个答案:

答案 0 :(得分:3)

我不认为这对于(成员)函数是可行的,因为g1::getg2::get必须在可用之前用实际参数进行实例化。

使用函数对象,您可以编写一个带有模板模板参数的函数,以及可变参数;然后,此函数可以使用您提供的参数实例化函数对象模板,并在绑定参数之前默认构造实例:

template <
    template <typename... Args> class VariadicFunc, 
    typename... ActualArgs >
auto mybind(ActualArgs... args)
    -> decltype(std::bind(VariadicFunc<ActualArgs...>(), args...))
{
    return std::bind(VariadicFunc<ActualArgs...>(), args...);
}

template <typename... Args>
struct functor
{
    void operator()(Args... args) {}
};

int main()
{
    mybind<functor>(1, 2); // instantiates a functor<int, int> and binds it
}

正如我之前所说的,这只能用于函数对象,而不能用于函数指针,因为你不能用模板函数指针来参数化模板。

答案 1 :(得分:1)

使用operator()代替get方法。它将以这种方式工作:

#include <functional>
#include <iostream>

struct g1{
    typedef void result_type;
    template <typename Arg>
    result_type operator()(Arg a) {
        std::cout << "g1()" << std::endl;
    }
};
struct g2{
    typedef void result_type;
    template <typename... Args>
    result_type operator()(Args... args) {
        std::cout << "g2()" << std::endl;
    }
};

int main()
{
    std::bind(g1(),2)();
    std::bind(g2(),2,1.1)();
    return 0;
}

不幸的是,我找不到任何方法让它与成员函数一起使用。但是对于真正的函数对象,它可以工作。

还不幸的是,您需要声明result_type。