使用 decltype 将其强制转换为 const [英] Using decltype to cast this to const

查看:30
本文介绍了使用 decltype 将其强制转换为 const的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试解决一个问题,其中 decltype 将大大简化事情,但我在 *this<上使用 decltype 时遇到了问题/code> 并添加 const 限定符.下面的示例代码演示了这个问题.

I'm attempting to solve a problem in which decltype will greatly simplify things, but I'm running into an issue using decltype on *this and adding a const qualifier. The sample code below demonstrates the problem.

#include <iostream>

struct Foo
{
  void bar()
  {
    static_cast<const decltype(*this)&>(*this).bar();
  }

  void bar() const
  {
    std::cout << "bar" << std::endl;
  }
};

int main(int argc, char* argv[])
{
  Foo f;
  f.bar(); // calls non-const method
  return 0;
}

代码在 MSVC2010 中编译,但会递归执行,直到发生堆栈溢出.

The code compiles in MSVC2010, but execution recurses until a stack overflow occurs.

Ideone 报告编译器错误

prog.cpp: In member function 'void Foo::bar()':
prog.cpp:7:38: error: 'const' qualifiers cannot be applied to 'Foo&'

如果我换行

static_cast<const decltype(*this)&>(*this).bar();

static_cast<const Foo&>(*this).bar();

它按预期工作.

我是否误用或误解了 decltype?

Am I misusing or misunderstanding decltype?

推荐答案

由于表达式 *this 不是 id-expression(即它没有命名实体,如变量),然后 decltype(*this) 给出表达式 *this 的类型.该类型是 Foo&,因此添加 const 限定符并对其进行引用不会改变任何内容:要么它默默地折叠为 Foo& (遵循引用折叠等规则),或者它是一个错误(一个 const 引用类型).我不确定哪种行为是正确的,实际上您已经找到了两个行为不同的编译器.在任何情况下都没有关系,因为这不是你想要的.

Since the expression *this is not an id-expression (i.e. it doesn't name an entity, like a variable), then decltype(*this) gives the type of the expression *this. That type is Foo&, so adding a const qualifier and making a reference to that doesn't change anything: either it silently collapse to Foo& (following rules like reference collapsing), or it's an error (a const reference type). I'm not sure which behaviour is correct, and you have in fact found two compilers which behave differently. In any case it doesn't matter because it's not what you want.

您可以使用 std::remove_reference<decltype(*this)>::type const& 代替,但这看起来有点难看.

You can use std::remove_reference<decltype(*this)>::type const& instead but that looks a bit ugly.

如果您仍然感到困惑:

int* p;
// decltype(p) is the type of the variable p (or, the declared type)
// int*

// decltype( (p) ) is the type of the expression p
// int*& because p is an lvalue

// decltype(*p) is the type of the expression *p
// int& because *p is an lvalue

这篇关于使用 decltype 将其强制转换为 const的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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