一个对象可以知道它自己的constness吗? [英] Can an object know its own constness?
问题描述
使用 decltype
和 std :: is_const
可以从外部检测变量的常数。 但是,对象是否也可以知道自己的constness?用法应该像:
With decltype
and std::is_const
the constness of a variable can be externally detected. But is it also possible for an object to know its own constness? Usage should be like:
#include <type_traits>
#include <iostream>
#include <ios>
struct Test
{
Test() {}
bool print() const
{
// does not work as is explained in http://stackoverflow.com/q/9890218/819272
return std::is_const<decltype(*this)>::value; // <--- what will work??
}
};
int main()
{
Test t;
const Test s;
// external constness test
std::cout << std::boolalpha << std::is_const<decltype(t)>::value << "\n";
std::cout << std::boolalpha << std::is_const<decltype(s)>::value << "\n";
// internal constness test
std::cout << std::boolalpha << t.print() << "\n";
std::cout << std::boolalpha << s.print() << "\n"; // <--- false??
}
输出 LiveWorkSpace 这是有可能的吗?
MOTIVATION :我想能够检测const成员函数在const对象上调用或者来自非const对象。该对象可以例如。表示缓存和成员视图。如果缓存是const,那么可以使用优化的绘制例程,而如果底层数据是非常量,则绘制例程需要定期检查数据是否被刷新。
MOTIVATION: I want to be able to detect whether a const member function is invoked on a const object or is coming from a non-const object. The object could e.g. represent a cache and the member a view. If the cache was const, one could presumably use an optimized draw routine, whereas if the underlying data was non-const, the draw routine would need to do periodically check if the data was refreshed.
注意:相关的问题询问如何破解const对象的构建,但我不太明白,如果这个答案意味着一个确定的NO我的问题。如果没有,我想捕获一个布尔的constness进一步使用。
NOTE: the related question asks how to break the build for const objects, but I don't quite understand if the answer to that implies a definite NO for my question. If not, I want to capture the constness in a boolean for further usage.
EDIT :正如@DanielFrey指出的,构造函数不是测试const的好地方。 const成员函数怎么样?
EDIT: as was pointed out @DanielFrey, the constructor is not a good place to test for constness. What about a const member function?
UPDATE :感谢大家纠正我最初的错误,提出了问题并提供了答案的各个部分(构造函数的定义不确定的一致性, 的价值,
const
,后缀 - 明显的重载技巧,我忽略了,和const引用别名漏洞潜伏在阴影)。对我来说这个问题是Stackoverflow的最好的。我决定选择@ JonathanWakely的答案,因为它展示了如何定义 Mutable
和 Immutable
类,以强化constness概念
UPDATE: Thanks everyone for correcting my initially ill-posed question and providing the various parts of the answer (constructors' ill-defined constness, rvaluedness of this
, the contextual meaning of const
, the -with hindsight- obvious overload trick that I had overlooked, and the const reference aliasing loophole lurking in the shadows). For me this question was Stackoverflow at its best. I decided to select @JonathanWakely's answer because it showed how to define Mutable
and Immutable
classes that strengthen the constness concept to achieve what I want in a foolproof way.
推荐答案
正如其他人所说的,你不能知道一个对象是否被声明为 const
。你只能判断它是否在 const
上下文中被调用,这是不一样的。
As others have stated, you cannot tell if an object was declared as const
from within a member function. You can only tell if it's being called in a const
context, which is not the same.
MOTIVATION:我想要能够检测const成员函数是在const对象上调用还是来自非const对象。该对象可以例如。表示缓存和成员视图。如果缓存是const,可以使用优化的绘制例程,而如果底层数据是非常量,绘制例程将需要周期性地检查数据是否被刷新。
MOTIVATION: I want to be able to detect whether a const member function is invoked on a const object or is coming from a non-const object. The object could e.g. represent a cache and the member a view. If the cache was const, one could presumably use an optimized draw routine, whereas if the underlying data was non-const, the draw routine would need to do periodically check if the data was refreshed.
你不能可靠地说出来。
struct A
{
void draw() { fut = std::async(&A::do_draw, this, false); }
void draw() const { fut = std::async(&A::do_draw, this, true); }
void update(Data&);
private:
void do_draw(bool this_is_const) const;
mutable std::future<void> fut;
};
A a;
const A& ca = a;
ca.draw(); // object will think it's const, but isn't
Data new_data = ...;
a.update(new_data); // do_draw() should recheck data, but won't
,通过定义单独的可变和不可变类型。
You can model it in the type system, by defining separate mutable and immutable types.
struct Base
{
virtual ~Base();
virtual void draw() const = 0;
protected:
void do_draw(bool) const;
};
struct MutableCache : Base
{
virtual void draw() const { fut = std::async(&Base::do_draw, this, false); }
void update();
};
struct ImmutableCache : Base
{
virtual void draw() const { fut = std::async(&Base::do_draw, this, true); }
// no update function defined, data cannot change!
};
现在,如果缓存创建为 ImmutableCache
你知道它不能改变,所以它取代了你以前的一个const对象的想法。 MutableCache
可以更改,因此需要检查刷新的数据。
Now if a cache is create as an ImmutableCache
you know it can't change, so that replaces your previous idea of a "const" object. A MutableCache
can change, so needs to check for refreshed data.
这篇关于一个对象可以知道它自己的constness吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!