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代碼中看到任何函數組合,你能告訴我它隱藏的位置嗎? –