常量成员函数中成员变量的类型

Type of member variables in a const member function

本文关键字:成员 类型 变量 函数 常量      更新时间:2023-10-16

当我将一个成员函数标记为 const 并检查成员变量的类型时,我得到了一些意想不到的结果。

#include <iostream>
#include <string>
template<typename T>
struct type_printer;
class const_type_test {
public:
void test() const {
type_printer<decltype(value)> _;
}
int& test2() const {
return value;
}
void test3() const {
auto& x = value;
type_printer<decltype(x)> _;
}
void test4() const {
auto* x = &value;
type_printer<decltype(*x)> _;
}
private:
int value;
};
int main(int argc, char** argv) 
{
const const_type_test x;
return 0;
}

我的理解是,当您在 const 方法中时,该方法实际上是一些名称损坏的名称,然后它们的参数类型是类名 const* const。我一直认为在 const 方法范围内,成员变量实际上是 const 的,即值将是 const int。但是,当使用编译器错误来推断我得到的类型时,我得到了我不期望的类型。

void const_type_test::test() const:聚合type_printer<int> _的错误输出类型不完整,无法定义,type_printer<decltype(value)> _;

所以我看到该类型被推断为 int。我以为这将是 const int,因为您无法更改值。我使用错误吗?还是我的理解有漏洞。

我想问的原因是编译器抱怨test2int&类型的绑定引用const int丢弃限定符。这正是我所期望的。可以将常量引用绑定到非常量引用。

示例 3 显示以下错误:错误:聚合type_printer<const int&> _具有不完整的类型,无法type_printer<decltype(x)> _定义。这就是我所期望的,它已被推导出为常量参考。

示例 4:还推导出一个我认为会是一个指针的type_printer<const int&>

渴望获得一些标准的参考,以找出我的知识漏洞在哪里。我也想知道在使用decltype时是否有一些奇怪的类型扣除规则让我绊倒。

decltype对类成员有特殊的规则。它返回成员的实际类型。如果您希望decltype考虑上下文(在 const 函数内(,则可以将表达式括在括号内。

无偏执:

void test() const {
type_printer<decltype(value)> _;
}
c.cpp:10:39: error: implicit instantiation of undefined template 'type_printer<int>'
type_printer<decltype(value)> _;

伴有偏执

void test() const {
type_printer<decltype((value))> _;
}
c.cpp:10:41: error: implicit instantiation of undefined template 'type_printer<const int &>'
type_printer<decltype((value))> _;

参考:

https://en.cppreference.com/w/cpp/language/decltype

如果参数是无括号的 id 表达式或无括号的类成员访问表达式,则 decltype 将生成此表达式命名的实体的类型。如果没有这样的实体,或者如果参数命名了一组重载函数,则程序格式不正确。

https://learn.microsoft.com/en-us/cpp/cpp/decltype-cpp?view=vs-2019

如果表达式参数是标识符或类成员访问,则 decltype(expression( 是表达式命名的实体的类型。如果没有此类实体或表达式参数命名一组重载函数,编译器将生成错误消息。

确保使用正确的类型。某些类型的范围比其他类型低