2

我正在玩仿函数组合,其中仿函数的返回类型取决于输入类型:

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 :(

是否有可能找到return_type使用decltype这样的方法std::bind?如果是这样,怎么做?

编辑:我替换U<T>typename T::U因为返回类型取决于类型。我希望这现在更清楚了。

编辑 2 (4?):添加了一个重现问题的可编译示例。

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

3 回答 3

3

忘记使用std::bind一分钟,只需尝试直接方法:

C<F> a;
C<G> b;
R<H> r{H{}, H{}};
a(b(r));

这甚至不会编译,所以bind版本不可能!

b(r)由于访问冲突而无效,并且如果a(b(r))由于尝试将临时绑定到非 const 左值引用而修复失败

于 2012-11-14T19:36:52.673 回答
1

解决了!我不得不替换C::operator()(IR& i)为,C::operator()(IR i)因为它是递归的。也许添加一个move构造函数IR会有助于提高性能,但是......?事实上,发生的事情是clang's 的错误不如gcc's 有用。好吧,怪我。

于 2012-11-14T19:17:38.877 回答
0

您的示例可以使用替代函数语法来解决:

#include <iostream>
#include <functional>

template<typename T>
struct Number {
  T t_;
  Number(T t) : t_(t) {}
  T operator+(T t) { return t_ + t; }
};

struct F {
  template<typename T>
  auto operator()(T x) -> decltype(x + 1)
  {
    return x + 1;
  }
} f, g;

int main(int argc, char* argv[])
{
  using namespace std::placeholders;
  auto h = std::bind(f, std::bind(g, _1));
  std::cout << h(Number<int>(1)) << std::endl;
}

并且value_type在这里不需要,而且它提供的问题是int从内部返回的,g(_1)而.int::value_typef

于 2012-11-14T18:18:04.550 回答