开发者

how to get rid of redundant type specifiers in a bind expression

Consider the following code:

开发者_StackOverflow
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;
}

Is it possible to get rid of the redundant template paramaters in case of (B) and (C) ? I would expect std::bind to automatically deduct the types from its paramaters.

I was thinking maybe writing a wrapper with variadic template arguments and with the use of decltype it might be possible to hide this redundant type specifications.

Note: I am using gcc 4.4


I don't think this is possible with (member) functions, because g1::get and g2::get must be instantiated with actual arguments before being usable.

With function objects, you could write a function that takes a template template parameter, as well as variadic parameters; this function could then instantiate the function object template with the arguments you gave it, and default-construct an instance before binding the parameters:

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
}

As I said before, this would only work with function objects, not with function pointers, since you cannot parameterized a template with template function pointer.


Use operator() instead of a get method. It will work this way:

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

Unfortunately, I could not find any way to make it work with member functions. But with real function objects, it works.

Also unfortunately, you need to declare result_type.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜