C ++ 11: return_type (для std :: bind) функтора, где возвращаемый тип основан на типе ввода

Я играю с композицией функтора, где тип возвращаемого функтора зависит от типа ввода:

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

2

Решение

Забудьте об использовании std::bind на минуту и ​​просто попробуйте прямой подход:

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

Это даже не скомпилируется, так что bind версия будет!

b(r) не действует из-за нарушения прав доступа, и если вы это исправите a(b(r)) не удается, потому что вы пытаетесь привязать временную ссылку к неконстантной lvalue-ссылке

3

Другие решения

Решил это! Я должен был заменить C::operator()(IR& i) с C::operator()(IR i) потому что это было рекурсивно. Возможно добавление move конструктор для IR поможет производительность, но …? На самом деле, случилось то, что clangошибки были не так полезны, как gcc«S. Ну, вини меня.

1

Ваш пример может быть решен с использованием альтернативного синтаксиса функции:

#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_type внутри ожидается f,

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector