当我把一个成员函数标记为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,因为你不能改变值。我是不是用错了decltype?还是我的理解有漏洞。
我想问的原因是,在 test2
编译器抱怨:绑定引用类型为 int&
到 const int
抛弃限定词。这正是我所期望的。可以将一个const引用绑定到非const引用。
例3显示了以下错误:错误:aggregation type_printer<const int&> _
类型不全,无法定义 type_printer<decltype(x)> _
. 这就是我所期望的,它已经被推导为一个const引用。
例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)> _;
With Paranthesis:
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.comwcpplanguagedecltype
如果参数是一个未括号的id表达式或 一个未括号的类成员访问表达式。,那么decltype就会产生这个表达式所命名的实体的类型。如果没有这样的实体,或者如果参数命名了一组重载函数,那么程序就是不正规的。
https:/docs.microsoft.comen-uscppcppdecltype-cpp?view=vs-2019。
如果表达式参数是一个标识符或 课堂成员访问decltype(expression)是由expression命名的实体的类型,如果没有这样的实体或者expression参数命名了一组重载函数,编译器就会产生错误信息。如果没有这样的实体,或者表达式参数命名了一组重载函数,编译器就会产生一个错误信息。