类模板实参推导(CTAD)报错:函数返回类型推导类类型问题
C++中
myManager_not_ok声明报错的原因解析 在使用g++ 10.2.0编译以下C++代码时,myManager_not_ok的声明会触发如下错误:
error: deduced class type ‘Manager’ in function return type
而另外两个几乎完全相同的Manager实例声明却能正常通过编译。以下是问题的详细解析:
示例代码
class Delegate { public: Delegate(int parameter) {} }; template<typename T_DelegateClass> class Manager : T_DelegateClass { public: Manager (T_DelegateClass theDelegate) : T_DelegateClass(theDelegate) {} }; int parameter=052; Manager myManager_not_ok( Delegate(parameter) ); // 报错行 Manager myManager_ok( Delegate( 052) ); Manager myManager_ok2( Delegate( (int)parameter) );
编译命令
g++ -std=c++17 deduced_class_type_in_function_return_type.cpp
问题解答
1. myManager_not_ok是否被解释为函数定义?
是的,这行代码被编译器优先解析为函数声明,而非Manager对象的定义。
2. 原因是什么?
这是C++标准中的「最令人头疼的解析(Most Vexing Parse)」规则:当一段代码同时符合对象定义和函数声明的语法时,编译器必须优先按照函数声明处理。
具体到报错行:
Manager被当作函数的返回类型(由于Manager是模板类,编译器尝试推导其模板参数,但无法完成推导,因此抛出错误)myManager_not_ok是函数名Delegate(parameter)被解析为函数的参数声明:参数类型为Delegate,参数名为parameter(这里的parameter会覆盖全局变量的名字,编译器优先将其识别为参数名)
3. 为什么其他Manager实例可以正常通过?
myManager_ok(Delegate(052)):052是数字字面量,无法作为参数名称使用,因此Delegate(052)不能被解析为参数声明,编译器只能将其识别为Delegate的临时对象,进而将整行解析为Manager对象定义,成功推导模板参数为Delegate。myManager_ok2(Delegate((int)parameter)):(int)parameter是带括号的类型转换表达式,不符合参数声明的语法规则,因此编译器同样只能将其解析为临时对象,正确识别为对象定义。
4. 这是C特性还是g的问题?
这是C++标准规定的特性,并非g的bug,所有符合C标准的编译器都会遵循这一解析规则。
内容的提问来源于stack exchange,提问作者LostInCompilation
相关产品推荐
相关产品推荐

