我如何“强制”在断言中使用const访问器?

问题描述 投票:1回答:1

我的google-fu不允许我找到任何关于此的内容,所以我在这里问。

我通过cppcheck运行我的c ++代码,并且它报告了assert调用中的某些代码可能有潜在的副作用。我以较小的规模复制了这个问题:

struct Obj
{
  int* myInt;

  Obj() : myInt( new int(3) ) {}
  ~Obj() { delete myInt; }

  const int* getInt() const { return myInt; }
};

struct C
{
  Obj* myObj;

  C() : myObj( new Obj() ) {}
  ~C() { delete myObj; }

  const Obj* getObj() const { std::cout << "const" ; return myObj; }
        Obj* getObj()       { std::cout << "non const" ; return myObj; }
};

int main()
{
  C c;

  assert( c.getObj()->getInt() ); // Outputs "non const"
  return 0;
}

(Qazxswpoi)

cppcheck是对的,这里:使用的Code on Coliru方法不是getObj()方法,它是非常数方法。

目标是1)满足cppcheck和2)确保这些断言没有副作用。

我怎么能告诉编译器使用const版本而不是非const getter?


我虽然有一种方法可以达到这个目的,但我发现它非常不干净,我宁愿在这种情况下使用更传统的方法来做这件事:const是基础对象。

const_cast
c++ const
1个回答
1
投票

由于c不是const:

assert( const_cast<const C&>(c).getObj()->getInt() );

执行非const版本。在C ++ 17中,您可以使用C c; c.getObj();

std::as_const()

这比你的建议略好:

assert( std::as_const(c).getObj()->getInt() );

如果c ++ 17不可用,您可以实现自己的as_const,并在断言语句中使用它:

assert( const_cast<const C&>(c).getObj()->getInt() );

并使用它:

template <class T> const T & as_const(T& obj) { return obj; } template <class T> void as_const(const T&& obj) = delete;

必须添加::前缀以避免因std命名空间中的对象的ADL导致std :: as_const的歧义。

© www.soinside.com 2019 - 2024. All rights reserved.