2013-08-04 1 views
2
#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 и не знаю, какие аргументы шаблона я должен передать. Почему он не обнаруживает типы.C++ Как реализовать compose2

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

+0

Вам нужно предоставить аргументы шаблона 'compose2', так как это шаблон;) –

+0

@CaptainObvlious Это сделает код слишком большим. Почему компилятор не обнаруживает типы из предоставленных объектов? – Ashot

+1

@ Ашот не может. Класс может иметь конструкторы, которые берут любые объекты. Но вы можете написать шаблон функции 'make_compose2'. – juanchopanza

ответ

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 , и параметры шаблона могут/будут выводиться из типов переданных параметров.

 Смежные вопросы

  • Нет связанных вопросов^_^