簡體   English   中英

std::functional 中的 C++ 可變參數函數模板

[英]C++ variadic function template in std::functional

基本上我想將多維積分與此遞歸集成。
但問題本身是一個普遍問題。 它不是特定於集成的。

#include "math.h"
#include <iostream>
#include <functional>

double f(double x,double y,double z){
    return x+y+z+1;
}

//Base
double redDim(std::function<double(double)> &f){
    return f(0); //a silly integrator for testing
}
// Recursion
template<typename Tfirst=double, typename... Trest>
auto redDim(std::function<double(Tfirst first,Trest... rest)> &f){
    return redDim([=](Trest... R){return redDim([=](double x){return f(x,R...);});});
}

int main(){
    std::cout<<redDim(f)<<std::endl;
    return 0;
}

問題是,編譯器說:

c:\C++\templateTutorial\templateTut.cpp: In function 'int main()':
c:\C++\templateTutorial\templateTut.cpp:24:19: error: no matching function for call to 'redDim(double (&)(double, double, double))'
     cout<<redDim(f)<<endl;
                   ^
c:\C++\templateTutorial\templateTut.cpp:12:8: note: candidate: 'double redDim(std::function<double(double)>&)'
 double redDim(std::function<double(double)> &f){
        ^~~~~~
c:\C++\templateTutorial\templateTut.cpp:12:8: note:   no known conversion for argument 1 from 'double(double, double, double)' to 'std::function<double(double)>&'
c:\C++\templateTutorial\templateTut.cpp:17:6: note: candidate: 'template<class Tfirst, class ... Trest> auto redDim(std::function<double(Tfirst, Trest ...)>&)'
 auto redDim(std::function<double(Tfirst first,Trest... rest)> &f){
      ^~~~~~
c:\C++\templateTutorial\templateTut.cpp:17:6: note:   template argument deduction/substitution failed:
c:\C++\templateTutorial\templateTut.cpp:24:19: note:   mismatched types 'std::function<double(Tfirst, Trest ...)>' and 'double(double, double, double)'
     cout<<redDim(f)<<endl;
                   ^
The terminal process terminated with exit code: 1

那么為什么f的類型不符合redDim()的要求呢?
因此,我什至無法測試,如果我的方法有效。
我希望你能幫助我!

函數指針不是std::function

模板參數推導不做任何類型轉換,除了一些 to-base 情況。

添加一個調用 std 函數 one 的redim( double(*f)(Args...) )模板。

template<class...Args>
auto redDim( double(*f)(Args...) {
  return redDim( std::function<double(Args...)>{ f } );
}

它應該工作。

這可以推導出函數指針的簽名。 然后它顯式轉換為std::function ,然后匹配您的其他redim函數。

您必須將其他 lambda 顯式轉換為std::function

// Recursion
template<typename Tfirst, typename... Trest>
auto redDim(std::function<double(Tfirst first,Trest... rest)> f){
  return redDim(
    std::function<double(Trest...)>{
      [=](Trest... R){
        return redDim(
          std::function<double(double)>{
            [=](double x){return f(x,R...);}
          }
        );
      }
    }
  );
}

活生生的例子

redDim最后一個redDim的參數更改為std::function<double(double)> (不是參考)。 或者,一個const&

基於 Yakk - Adam Nevraumont 的回答,應該編譯以下代碼:

#include "math.h"
#include <iostream>
#include <functional>

double f(double x,double y,double z){
    return x+y+z+1;
}

//Base
double redDim(const std::function<double(double)> &f){
    return f(0); //a silly integrator for testing
}
// Recursion
template<typename Tfirst=double, typename... Trest>
auto redDim(const std::function<double(Tfirst first,Trest... rest)> &f) {

    return redDim(
    std::function<double(Trest...)>{
        [=](Trest... R)->double{return redDim([=](double x){return f(x,R...);});}});
}

template<class...Args>
auto redDim( double(*f)(Args...)) {
  return redDim( std::function<double(Args...)>{ f } );
}

int main(){
    std::cout<<redDim(f)<<std::endl;
    return 0;
}

正如 Yakk 已經指出的那樣, std::function和函數指針沒有相同的類型。 請注意,我還將redDim的參數類型redDimconst std::function<...> &) 您還可以使用&&語法傳遞rvalue引用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM