2016-12-15 7 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)); 
} 

としてそれをテスト:

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 

コンソール出力は次のようになります。

vector<int> tempVect_(10, 0); 

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

は、エラーが、残念ながら私を与えます以下:

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

: あなたは、おそらくこのように、ラムダと1を作成することができます。 – molbdnilo

+2

'startofSequence'と' threadStep'の両方が整数( 'int'と' unsigned int')の場合、地球上でどのように 'T'がfloatとして解決されますか?私はそれを再現することはできません。 'C2780'について - あなたの' std :: plus'コンストラクタはwierdのようですが、なぜあなたはそれにパラメータを渡していますか? – Ap31

+1

私は個人的に 'iota_stepa'の関数パラメータにして、' Func'のようなテンプレート型を与えます。そうすれば、ラムダのような他の "関数"を渡すことができます。 – 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単独で見ると、元の行には非常に具体的なエラーがエラーメッセージに反映されており、固定線でその特定のエラーが修正されます。固定回線がより大きなコンテキストに適しているかどうかはわかりません。元のコードに複数のバグがある可能性があります。 –

関連する問題