将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