C++的evaluation strategy为函数参数是总是 “由值” “急切” 和通常。什么意思简短的版本是,一个由函数调用序列,如
x = a(b(c(1)));
是完全一样
{
auto t0 = c(1);
auto t1 = b(t0);
x = a(t1);
}
(auto t0
的意思是“给t0
任何类型是最合适的”;它是一个相对较新的功能,可能无法在C++编译器中使用。大括号表示临时变量t0
和t1
在分配给x
后被销毁。)
我提出这个问题是因为你一直在讨论函数“以函数作为输入”。有是编程语言,如R,其中写a(b(1))
会通过表达b(1)
到a
,只有真正呼叫b
时a
要求表达进行评估。我想 MATLAB不是那样的,但我可能是错的。无论如何,C++肯定是而不是那样。在C++中,a(b(1))
首先评估b(1)
,然后将该评估的结果传递给a
; a
无法找出结果来自b
的电话。只有在C++中正确描述为“以另一个函数作为输入的函数”的情况将对应于您使用feval
的示例。
现在:你已经证明了MATLAB代码的最直接的翻译是
#include <stdio.h>
static double a(double x) { return 2*x; }
static double b(double y) { return 3*y; }
static double c(double p, double q) { return a(p) * b(q); }
static double d(double r) { return a(b(r)); }
static double f1(double (*arg1)(double))
{ return arg1(2.0); }
int main()
{
printf("%g\n", a(b(1))); // prints 6
printf("%g\n", c(1,2)); // prints 12
printf("%g\n", d(1)); // prints 6
printf("%g\n", f1(d)); // prints 12
printf("%g\n", f1(a)); // prints 4
return 0;
}
(C++已经不需要像feval
明确的语法,因为输入的参数声明,double (*arg1)(double)
告诉编译器arg1(2.0)
是有效的。在旧的代码,你可能会看到(*arg1)(2.0)
但是这不是必需的,我认为它使代码的可读性。)
(我在此代码中使用printf
,而不是C++的输入输出流,部分原因是因为我个人认为printf
是比iostreams更符合人体工程学,部分原因是这使得这个程序也是一个有效的C程序具有相同的语义。例如,如果你学习C++的原因是因为你想编写MATLAB扩展,那么,如果你坚持使用普通的C,最后一次检查的实际上更容易。)
有显着性差异;例如,MATLAB函数接受向量,而这些C++函数只取单值;如果我希望b
致电c
,我将不得不将它们交换或在b
以上写上c
的“前向声明”;和C++中(除了一些你现在不需要担心的例外),你所有的代码都必须在一个或另一个函数中。学习这些差异是学习C++的一部分,但是您不需要将自己与模板,lambda表达式和类等混淆在一起。首先坚持使用固定类型签名的免费功能。
最后,如果我没有提到,在
static double c(double p, double q) { return a(p) * b(q); }
到a
和b
呼叫可能在任意顺序发生,我将是失职。有谈到改变这一点,但还没有发生。
可能类似于[C++ lambda函数](http://en.cppreference.com/w/cpp/language/lambda)? '@(x)'在MATLAB中究竟做了什么? –
我还是不明白'fun1'。它看起来像一个参数'c',忽略了这个参数,并且无条件地*返回*'a'。然后,你*调用*'fun1',传递'1',这应该被忽略,但不知怎的,你得到的答案是2,而不是'@(x)2 * x'或'a'。 WTF? – zwol
函数组合是一个接受两个函数并返回另一个函数的操作。我没有在matlab代码中看到任何函数组合,你能告诉我它隐藏的位置吗? –