Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c++;将参数数目可变的函数作为参数传递给其他函数 我编写了一个C++类,它解析表达式,如“2 *SqRT(5)+1”。我创建了一个名为c_function的类,它“表示”了常见的数学函数,如sqrt、sin、cos等。如下所示: class c_function { std::string name; double (*function)(double); public: c_function(std::string fname, double (*ffunction)(double)) { name = fname; function = ffunction; } // ... };_C++_Variadic Functions - Fatal编程技术网

c++;将参数数目可变的函数作为参数传递给其他函数 我编写了一个C++类,它解析表达式,如“2 *SqRT(5)+1”。我创建了一个名为c_function的类,它“表示”了常见的数学函数,如sqrt、sin、cos等。如下所示: class c_function { std::string name; double (*function)(double); public: c_function(std::string fname, double (*ffunction)(double)) { name = fname; function = ffunction; } // ... };

c++;将参数数目可变的函数作为参数传递给其他函数 我编写了一个C++类,它解析表达式,如“2 *SqRT(5)+1”。我创建了一个名为c_function的类,它“表示”了常见的数学函数,如sqrt、sin、cos等。如下所示: class c_function { std::string name; double (*function)(double); public: c_function(std::string fname, double (*ffunction)(double)) { name = fname; function = ffunction; } // ... };,c++,variadic-functions,C++,Variadic Functions,然后我有一个不同的类,它包含这些c_函数对象的std::vector: class expression { std::vector<c_function> functions; // etc... public: // ctor: expression(/* ... */) { // ... functions.push_back(c_function("SQRT", sqrt)); functions.push_back(c_functi

然后我有一个不同的类,它包含这些
c_函数
对象的
std::vector

class expression {
  std::vector<c_function> functions;
  // etc...

public:
  // ctor:
  expression(/* ... */) {
    // ...
    functions.push_back(c_function("SQRT", sqrt));
    functions.push_back(c_function("SIN" , sin));
    functions.push_back(c_function("COS" , cos));
    // ...
  }

};
并使用了两个构造函数:

c_function(std::string fname, double (*ffunction)(double)) {
  name = fname;
  argumentCount = 1;
  function1 = ffunction;
  function2 = NULL;
};
c_function(std::string fname, double (*ffunction)(double, double)) {
  name = fname;
  argumentCount = 2;
  function1 = NULL;
  function2 = ffunction;
};
并将方法添加到
表达式
类中:

class c_function {
  std::string name;
  unsigned int argumentCount;
  double (*function1)(double);
  double (*function2)(double, double);

  // ...
};
// add custom function with one argument
void addFunction(std::string fname, double (*ffunction)(double));

// add custom function with two arguments
void addFunction(std::string fname, double (*ffunction)(double, double));
这样就可以定义

double Expression_Area(double width, double height) {
  return (width * height);
}
并使用

myExpression.addFunction("AREA", Expression_Area);
这很好,这样我还可以添加更多的函数“属性”和函数构造函数,允许任意数量的参数,但是

  • 支持的参数数量总是有限制的
  • 由于在表达式的解释中有多个构造函数、添加函数的方法和代码,而仅仅因为参数的数量可能不同,代码就会变得丑陋
  • 我想知道是否有一种方法可以支持具有任意数量更一般参数的函数。我尝试将
    c_函数
    类更改为:

    class c_function {
      std::string name;
      unsigned int argumentCount;
      double (*function)(...);
      // ...
    
    };
    
    但是这不起作用,因为具有固定数量参数的函数不被
    (…)
    接受

    有没有办法用一个构造函数、一个函数“属性”等来解决这个问题?

    C++11以后的版本 在C++11中,您可以使用可变模板声明一个类,该类将接受具有可变参数数的函数:

    #include <iostream>
    #include <string>
    
    double bar(double x) {
      return x;
    }
    
    double bar2(double x, double y) {
      return x+y;
    }
    
    template <typename... Args>
    class Foo {
    public:
      Foo (const std::string& name, double (*func)(Args...))
        : name_{name}, func_{func} {}
    
      double call(Args... args) {
        return func_(args...);
      }
    
      // Thanks to W.F. for reminding me of the operator() overload
      // This does the same thing as a call to the "call" method.
      double operator()(Args... args) {
        return func_(args...);
      }
    
    private:
      std::string name_;
      double (*func_)(Args...);
    };
    
    int main() {
      Foo<double> t1("test1", bar);
      Foo<double, double> t2("test2", bar2);
    
      // NOTE: in C++17 you can declare Foo without the template
      // arguments: they will be deduced.
      // Foo t1("test1", bar); // C++17
      // Foo t2("test2", bar2); // C++17
    
      std::cout << t1.call(14) << ' ' << t2(14, 56) << std::endl;
    
      return 0;
    }
    

    您可以重载
    operator()
    ,让它看起来更像函数调用:)@W.F.是的,不管怎样…)谢谢佐拉瓦的好提示。使用代码复制的解决方案是我已有的(有点不同,但逻辑上相同)。我的错误是,在解释时调用函数时无法避免重复,因为函数父级之间的参数收集在向量中,必须以某种方式传递给函数。这可能是在隐式循环中(我记得从FORTRAN格式语句),但我相信在C++中是不可用的。无论如何,您的提示将代码重复减少到一个地方而不是四个地方。@Armin:可能有一种方法可以做到这一点(但可能会很难看,而且几乎肯定需要C++11或C++17才能做到),但您肯定应该问另一个有关此问题的问题。我会考虑的,但可能其他人会知道怎么做。去问:)@Zorawar:好了,我期待着答案。
    #include <iostream>
    #include <string>
    
    double bar(double x) {
      return x;
    }
    
    double bar2(double x, double y) {
      return x+y;
    }
    
    class Foo1 {
    public:
      // let's typedef the function pointer for two reasons:
      //   1. readability
      //   2. duplicating the class for a different number of arguments
      //      means we need to do less modifications to the code because
      //      we can catch a few changes in one line here.
      typedef double (*Function)(double);
    
      Foo1 (const std::string& name, const Function func)
        : name_(name), func_(func) {}
    
      double operator()(double x) {
        return func_(x);
      }
    
    private:
      std::string name_;
      Function func_;
    };
    
    class Foo2 {
    public:
      typedef double (*Function)(double, double);
    
      Foo2 (const std::string& name, const Function func)
        : name_(name), func_(func) {}
    
      double operator()(double x, double y) {
        return func_(x, y);
      }
    
    private:
      std::string name_;
      Function func_;
    };
    
    // etc. for classes Foo3, Foo4, ... up until you think you will
    // need no more.
    
    int main() {
      Foo1 t1("test1", bar);
      Foo2 t2("test2", bar2);
    
      std::cout << t1(14) << ' ' << t2(14, 56) << std::endl;
    
      return 0;
    }
    
    template <typename T, typename... Args>
    class Foo {
    public:
      typedef T (*Function)(Args...);
    
      Foo (const std::string& name, const Function func)
        : name_{name}, func_{func} {}
    
      T operator()(Args... args) {
        return func_(args);
      }
    
    private:
      std::string name_;
      Function    func_;
    };