I'm playing with functor composition, where the return type of a functor depends on the input type:
template<typename V>
class F
{
protected:
V v_;
public:
using return_type = ?;
F(V v) : v_(v) {}
template<typename T>
typename T::U operator()(T t)
{
v.method(t);
}
};
...
X x;
Y y;
F<X> f(x);
F<Y> g(y);
auto h = std::bind(f, std::bind(g, _1));
h(...); // problem is here :(
Is it possible to find return_type
using decltype
so that std::bind
will work? If so, how?
Edit: I replace U<T>
with typename T::U
because the return type depends on the type. I hope this is clearer now.
Edit 2 (4?): Added a compilable example that reproduces the problem.
#include <functional>
using namespace std::placeholders;
template<typename I>
struct R
{
using IT = I;
R(I x, I y) : b(x), e(y) {}
I b;
I e;
};
template<typename IN, typename II>
class CI
{
CI(II i) {}
};
template<typename IN>
class C
{
template<typename IR>
R<CI<IN, typename IR::IT> >
operator()(IR& i)
{
return R<CI<IN, typename IR::IT> >(
CI<IN, typename IR::IT>(i.b),
CI<IN, typename IR::IT>(i.e));
}
};
struct F {};
struct G {};
struct H {};
int main(int argc, char* argv[])
{
C<F> a;
C<G> b;
auto c = std::bind(a, std::bind(b, _1));
R<H> r{H{}, H{}};
c(r);
}
Forget about using std::bind
for a minute and just try the direct approach:
C<F> a;
C<G> b;
R<H> r{H{}, H{}};
a(b(r));
This won't even compile, so there's no way the bind
version will!
b(r)
isn't valid because of an access violation, and if you fix that a(b(r))
fails because you try to bind a temporary to a non-const lvalue-reference