將Wrapper::get()
標記爲pure
成員函數是否有效?它僅取決於隱含的Wrapper
實例,但該數據可能會更改。
是的,Wrapper::get()
符合gcc的pure
屬性的要求。然而,請注意,__attribute__((pure))
並不意味着在學術意義上是純粹的,即具有參照透明性。後者可以通過更嚴格的__attribute__((const))
送交:
__attribute__((const))
很多函數不檢查除它們的參數的任何值,並 除了有返回值沒有影響。基本上這只是 稍差一些,比pure
屬性稍差一些,因爲 函數不允許讀取全局內存。
注意,有指針參數,且檢查 指出,必須不聲明const
數據的功能。同樣,調用 非const
函數的函數通常不能是const
。對於const
函數, 沒有意義返回void
。
但由於Wrapper::get()
不具備通過__attribute__((const))
隱含引用透明的性質,它不能被打成這樣。
編輯
功能關於pure
-ness擔保(在GCC的意義上),可用於優化只是一個代碼塊不包含寫入全局存儲器(和,特別是,不穿插到對非pure
函數的調用)。示例:
struct Wrapper {
int i;
int get() const __attribute__((pure)) { return i; }
void set(int x) { i = x; }
};
long foo(Wrapper* w)
{
// w->get() can be computed once
return 2 * w->get() * w->get();
}
long bar(Wrapper* w)
{
// w->get() can be computed once (even though below code writes to memory,
// that memory is freshly allocated and cannot be accessed by w->get())
long result = 2;
result *= w->get();
result *= w->get();
return result;
}
long baz(Wrapper* w)
{
// both w->get()s must be evaluated, since non-pure code occurs between them
long result = 2;
result *= w->get();
std::cout << "Result after the first muliplication: " << result << std::endl;
result *= w->get();
return result;
}
本文可能與http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0078r0相關。pdf – Danh
隱含對象(this)參數仍然是一個參數。語法無關緊要。如果foo(x)或x.foo()或其他什麼都調用。 –
@Danh從這篇論文中不完全清楚這個問題的答案是什麼。這似乎有點不置可否。 – Barry