how to get rid of redundant type specifiers in a bind expression
Consider the following code:
开发者_StackOverflowstruct 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.
精彩评论