当我将一个成员函数标记为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方法时,该方法实际上是一些名称乱码,那么它们的参数类型为classname const * const。我一直认为在const方法范围内,成员变量实际上是const,即value将是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显示以下错误:错误:聚合type_printer<const int&> _
的类型不完整,无法定义type_printer<decltype(x)> _
。我希望将其推导出为const引用。
示例4:还推导了一个type_printer<const int&>
,我认为这是一个指针。
热衷于参考标准,以找出我所知道的漏洞所在。我还想知道在使用decltype
时是否有一些奇怪的类型推导规则使我绊倒。
答案 0 :(得分:7)
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://docs.microsoft.com/en-us/cpp/cpp/decltype-cpp?view=vs-2019
如果expression参数是标识符或类成员访问权限,则decltype(expression)是由expression命名的实体的类型。如果没有这样的实体,或者表达式参数指定一组重载函数,则编译器将产生错误消息。
答案 1 :(得分:0)
确保使用正确的类型。某些类型的范围比其他类型低