为什么C++17带初始化器的if语句未按预期工作?
错误原因
这个错误是C++中auto返回类型的推导规则和类成员函数的分析顺序共同导致的:
- C++标准要求:返回值类型为
auto的函数,调用点必须在函数定义之后,编译器只有看到函数的return语句,才能推导出实际的返回类型。 - 对于类内直接定义的成员函数,编译器的处理逻辑是:先扫描整个类,收集所有成员的声明信息,再按照成员函数在类内出现的顺序,逐个分析函数体的内容。
对应示例代码:
struct A { auto g1() { return true; } void f() { if (auto b = g1(); b) // ok { return; } if (auto b = g2(); b) // error: use of 'auto A::g2()' before deduction of 'auto' { return; } } auto g2() { return true; } };
- 分析
f函数体时,g1的完整定义已经出现在f之前,编译器已经推导得到g1的返回类型为bool,所以g1()调用合法。 - 此时
g2的定义还在f的后面,编译器只知道有auto A::g2()这个成员函数,但还没看到它的函数体,无法完成返回类型推导,因此调用g2()时报错。
如果要修复这个问题,可以选择以下任意一种方案:
- 将
g2的定义移动到f的定义之前 - 给
g2显式指定返回类型,不用auto推导 - 给
g2添加尾置返回类型声明,例如auto g2() -> bool;
内容的提问来源于stack exchange,提问作者xmllmx
相关产品推荐
相关产品推荐

