常量成员函数中成员变量的类型
Type of member variables in a const member function
当我将一个成员函数标记为 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,因为您无法更改值。我使用错误吗?还是我的理解有漏洞。
我想问的原因是编译器抱怨test2
:int&
类型的绑定引用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( 是表达式命名的实体的类型。如果没有此类实体或表达式参数命名一组重载函数,编译器将生成错误消息。
确保使用正确的类型。某些类型的范围比其他类型低
- 根据模板类型选择类模板的成员类型?
- 函数模板签名中忽略的成员类型def 的访问说明符
- 在C++如何从数组中提取成员并返回成员类型的数组?
- C++从成员类型中扣除类型的功能模板?
- 无法初始化以 std::byte 作为成员类型的位字段
- 构造函数可以更改默认成员类型吗?
- 使用相同方法但不同成员类型构建类的最佳方法
- 允许通过指向方法的成员参数的指针来推断模板参数所指向的成员类型
- 使用 std::条件根据模板参数选择成员类型
- CRTP:如何推断要用作返回类型的成员类型?
- 对成员类型的成员方法使用 std::result_of<>
- C :可以从类及其受保护的成员类型继承可以继承吗?
- 如何在不指定不必要的模板参数的情况下使用模板类的成员类型
- 基类数据成员类型取决于派生类
- C 多态性:允许模棱两可的成员类型
- 使用使用成员类型别名的构造函数来推论类模板参数
- 获取与在模板参数中传递的函数成员类型相同的类
- 如果静态成员未初始化并且成员类型是类本身,该怎么办?
- boost::bind 无法绑定到纯虚拟基类中定义的非静态函数模板成员类型
- 将联合强制转换为其成员类型之一