адаптер — c ++ Как реализовать compose2

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <algorithm>
#include <ctime>
#include <iterator>
#include <string>
#include <numeric>

template <typename BinaryFunction, typename UnaryFunction1, typename UnaryFunction2>
struct compose2 {
compose2(BinaryFunction binFunc, UnaryFunction1 unFunc1, UnaryFunction2 unFunc2)
: m_binFunc(binFunc)
, m_unFunc1(unFunc1)
, m_unFunc2(unFunc2)
{}
typedef typename BinaryFunction::return_type return_type;
typedef typename UnaryFunction1::argument_type argument_type;
return_type operator()(argument_type arg) {
return m_binFunc(m_unFunc1(arg), m_unFunc2(arg));
}

BinaryFunction m_binFunc;
UnaryFunction1 m_unFunc1;
UnaryFunction2 m_unFunc2;
};

int main() {
std::vector<int> v;
v.push_back(1);
v.push_back(75);
v.push_back(10);
v.push_back(65);
v.push_back(15);
v.push_back(78);
v.push_back(14);
v.push_back(19);
int x = 10, y = 20;

std::vector<int>::iterator it = std::find_if(v.begin(), v.end(),
compose2(
std::logical_and<bool>(),
std::bind1st(std::less<int>(), x),
std::bind1st(std::greater<int>(), y)
));

std::cout << (it - v.begin()) << std::endl;
}

Я пытался реализовать compose2 адаптер, но это не компилируется. я получаю main.cpp:43:29: error: missing template arguments before ‘(’ token и не знаю, какие аргументы шаблона я должен передать. Почему это не обнаруживает типы.

Я знаю, что это реализовано в boost или другой библиотеке или в новом стандарте c ++ 11. Но я только хочу знать, почему моя реализация терпит неудачу. Благодарю.

2

Решение

Компилятор может выводить аргументы шаблона только для шаблонов функций, а не шаблонов классов. Это оставляет вам несколько вариантов: наиболее очевидным (но часто наименее удобным) является указание параметров шаблона при создании экземпляра compose2,

Маргинально менее очевидно, но часто более удобно создавать шаблон функции, который выводит параметры и создает compose2 объект, использующий выведенные типы:

template<class BinaryFunction, class UnaryFunction1, class UnaryFunction2>
compose2<BinaryFunction, UnaryFunction1, UnaryFunction2>
make_compose2(BinaryFunction binFunc, UnaryFunction1 unFunc1, UnaryFunction2 unFunc2) {
return compose2_t<BinaryFunction, UnaryFunction2, UnaryFunction2>
(binFunc, unFunc1, unFunc2);
}

Тогда клиентский код будет использовать make_compose2 вместо compose2и параметры шаблона могут / будут выведены из типов передаваемых параметров.

2

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

Других решений пока нет …