为何不同长度const char(&)[N]在compare2模板中无编译错误?
为什么compare2传入不同长度的const char数组不会报错?
已知调用compare1传入不同长度的const char数组时会触发编译错误,原因已明确,但为何调用compare2传入不同长度的const char数组时不会报错?相关代码及编译错误信息如下:
#include <iostream> #include <vector> #include <string> using namespace std; template<typename T1, typename T2> const T1& compare1(const T1& a, const T2& b) // 传入不同长度数组可能报错 { return a < b ? a : b; } template<typename T1, typename T2> bool compare2(const T1& a, const T2& b) // 为什么不同长度数组不会报错? { return a < b ? a : b; } int main() { compare1("hello", "world"); // 编译成功 compare1("hello", "worldx"); // 如预期编译失败 compare2("hello", "worldx"); // 编译通过,不符合预期 }
编译错误信息(针对compare1的调用):
<source>: In instantiation of 'const T1& compare1(const T1&, const T2&) [with T1 = char [6]; T2 = char [7]]': <source>:21:13: required from here 21 | compare1("hello", "worldx"); | ~~~~~~~~^~~~~~~~~~~~~~~~~~~ <source>:10:19: error: invalid initialization of reference of type 'const char (&)[6]' from expression of type 'const char*' 10 | return a < b ? a : b; | ~~~~~~^~~~~~~
原因分析
先看compare1的报错逻辑
当调用compare1("hello", "worldx")时,模板参数被推导为T1=char[6]、T2=char[7],函数返回值是const char(&)[6](绑定到6元素char数组的常量引用)。
在三元表达式a < b ? a : b中:
- 数组类型在参与表达式运算时会隐式转换为指向首元素的指针,所以
a(char[6]引用)会转成const char*,b(char[7]引用)也会转成const char*。 - 三元运算符的结果类型是两个分支的公共类型,这里就是
const char*。 - 但函数要求返回
const char(&)[6],用指针类型去初始化数组引用是C++不允许的,因此触发编译错误。
再看compare2为什么不报错
compare2的返回值是bool,整个逻辑和compare1有本质区别:
- 同样,
a < b会先把两个数组转成const char*,比较的是指针地址(注意:不是字符串内容,是数组在内存中的地址)。 - 三元表达式
a < b ? a : b的结果是a或b,但因为最终要转换成bool返回:- 不管是
a(char[6]引用)还是b(char[7]引用),都会先隐式转成const char*; - 而指针类型可以被隐式转换成
bool(非空指针都会被转为true)。
- 不管是
- 整个过程没有类型不匹配的问题,因此编译可以正常通过。
内容的提问来源于stack exchange,提问作者Inquisitive
相关产品推荐
相关产品推荐

