2013-08-04 71 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 ,並且模板參數可以/將從傳遞參數的類型推導出來。