Bla*_*son 12 c++ constants type-deduction
当我有一个标记为 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;
}
Run Code Online (Sandbox Code Playgroud)
我的理解是,当您使用 const 方法时,该方法实际上是一些名称混淆的名称,然后它们的参数类型是 classname const* const。我一直认为在 const 方法范围内,成员变量实际上是 const,即值将是 const int。但是,当使用编译器错误来推断类型时,我得到了我不期望的类型。
错误输出void const_type_test::test() const:aggregatetype_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)> _。这是我所期望的,它被推导出为常量引用。
示例 4:还推导出 a type_printer<const int&>,我认为它是一个指针。
渴望获得对标准的一些参考,以找出我知识中的漏洞。我还想知道在使用时是否有一些奇怪的类型推导规则decltype让我绊倒。
decltype对班级成员有特殊规定。它返回成员的实际类型。如果要decltype考虑上下文(在 const 函数内),则可以将表达式括在括号内。
不带括号:
void test() const {
type_printer<decltype(value)> _;
}
Run Code Online (Sandbox Code Playgroud)
c.cpp:10:39: error: implicit instantiation of undefined template 'type_printer<int>'
type_printer<decltype(value)> _;
Run Code Online (Sandbox Code Playgroud)
带括号:
void test() const {
type_printer<decltype((value))> _;
}
Run Code Online (Sandbox Code Playgroud)
c.cpp:10:41: error: implicit instantiation of undefined template 'type_printer<const int &>'
type_printer<decltype((value))> _;
Run Code Online (Sandbox Code Playgroud)
参考:
https://en.cppreference.com/w/cpp/language/decltype
如果参数是无括号的 id-expression 或无括号的类成员访问 expression,则 decltype 产生由此表达式命名的实体的类型。如果没有这样的实体,或者参数命名了一组重载函数,则程序格式错误。
https://docs.microsoft.com/en-us/cpp/cpp/decltype-cpp?view=vs-2019
如果表达式参数是标识符或类成员 access,则 decltype(expression) 是由表达式命名的实体的类型。如果没有这样的实体或表达式参数命名一组重载函数,编译器会产生错误消息。