一个对象可以知道它自己的constness吗? [英] Can an object know its own constness?

查看:129
本文介绍了一个对象可以知道它自己的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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆