2016-12-15 120 views
2

我想將標準化的C++二進制函數傳遞給模板函數,但不知何故,我沒有得到它的工作。如何將二進制函數傳遞給模板函數C++

以下是我試圖做到這一點:

template<template <typename> typename Pred,typename T, typename Iterator> 
void iota_stepa(Iterator begin, Iterator end, T startofSequence_, T threadStep) 
{ 
    int currMaxThreads = startofSequence_; 
    bool first = true; 
    generate(begin, end, Pred<T>(currMaxThreads, threadStep)); 
} 

,並測試它:

vector<int> tempVect_(10, 0); 

iota_stepa<std::plus>(begin(tempVect_),end(tempVect_),1,thread::hardware_concurrency()); 

讓我遺憾的錯誤:

Severity Code Description Project File Line Suppression State 
Error C2440 '<function-style-cast>': cannot convert from 'initializer list' to 'std::plus<int>' 
Error C2672 'generate': no matching overloaded function found FractalCarpet 
Error C2780 'void std::generate(_FwdIt,_FwdIt,_Fn0)': expects 3 arguments - 2 provided FractalCarpet 

控制檯輸出看起來像如下:

1> c:\users\mtunca\documents\esd\sps\fractalcarpet\main.cpp(55): note: see reference to function template instantiation 'void iota_stepa<std::plus,int,std::_Vector_iterator<std::_Vector_val<std::_Simple_types<float>>>>(Iterator,Iterator,T,T)' being compiled 
1>   with 
1>   [ 
1>    Iterator=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<float>>>, 
1>    T=int 
1>   ] 
1>c:\users\mtunca\documents\esd\sps\fractalcarpet\main.cpp(34): error C2672: 'generate': no matching overloaded function found 
1>c:\users\mtunca\documents\esd\sps\fractalcarpet\main.cpp(34): error C2780: 'void std::generate(_FwdIt,_FwdIt,_Fn0)': expects 3 arguments - 2 provided 
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm(1532): note: see declaration of 'std::generate' 

有人可以幫助我,如何解決這個問題?

+0

有通常在輸出窗口更多有用的信息比在錯誤列表。 – molbdnilo

+2

如果'startofSequence'和'threadStep'都是整數('int'和'unsigned int'),地球上的T如何解析爲float?我不能完全重現它。至於'C2780' - 你的'std :: plus'構造函數看起來很奇怪,爲什麼你要傳遞參數呢? – Ap31

+1

就個人而言,我只是將它作爲'iota_stepa'的函數參數,並給它一個像'Func'這樣的模板類型。這樣你就可以傳遞其他「函數」,比如lambda。 – NathanOliver

回答

3

std::generate需要一個發電機,可以調用像gen()。 您可以創建一個有拉姆達,也許是這樣的:

template<template <typename> class Pred, typename T, typename Iterator> 
void iota_stepa(Iterator begin, Iterator end, T startofSequence_, T threadStep) 
{ 
    bool first = true; 
    T current; 
    auto gen = [&]() -> T 
    { 
     if(first) { 
      current = startofSequence_; 
      first = false; 
     } else { 
      current = Pred<T>() (current, threadStep); 
     } 
     return current; 
    }; 
    generate(begin, end, gen); 
} 
+0

這解決了這個問題。謝謝!我的目的是生成一個像{128,256,512,...}這樣的清晰地圖,這樣我就可以在GPU上用不同的線程進行性能分析。 –

0
Pred<T>(currMaxThreads, threadStep)); 

Pred<T>是一種類型。你需要構建一個實際可調用對象:

Pred<T>()(currMaxThreads, threadStep)); 

然而,這可能不會是最後一個參數std::generate。後者需要一個沒有參數的可調用對象,大概持有一個狀態(否則調用std :: fill woud就足夠了)。目前還不清楚如何調整任意二元函數來填補這一角色。

+1

'Pred ()(currMaxThreads,threadStep));'不能正確。當'generate'需要一個函數對象時,它會返回一個值。 – NathanOliver

+0

這是一個受過教育的猜測。我無法完全重現錯誤。請發佈[mcve]。 –

+0

@NathanOliver單獨觀看,原始行在錯誤消息中有一個非常具體的錯誤,固定行修復了特定的錯誤。固定線路是否適合更大的環境,我不知道。也許原始代碼有多個bug –