2013-08-04 32 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

@Ashot它不能。这个类可以有构造函数接受任何类型的对象。但是你可以写一个'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 ,并且模板参数可以/将从传递参数的类型推导出来。