为什么C++编译器无法推导带偏移的数组大小对应的模板参数
问题核心原因
你遇到的报错是C++模板实参推导的标准规则导致的:n + 1 属于非推导上下文,编译器无法从传入的实参反推出n的取值。
具体规则说明
C++标准中明确约定了一系列不会参与模板实参推导的场景,其中一条就是:如果模板参数仅出现在某个子表达式内部,而不是直接作为参数类型的顶层元素,就不会参与推导。
你给出的代码中:
template<unsigned n> void test(char const (*)[n + 1]) { } int main() { char const arr[] = "Hi"; test(&arr); }
数组大小的位置是表达式n + 1,n是这个加法表达式的子元素,不属于顶层的可推导元素,所以编译器收到char const (*)[3]类型的实参时,不会自动解方程n + 1 = 3得到n = 2,只会直接判定无法推导n,忽略这个模板候选,最终报出你看到的错误:
note: candidate template ignored: couldn't infer template argument 'n'
为什么改成n就能编译
当你把数组大小改成n时,n直接作为数组大小的顶层元素,不属于非推导上下文,编译器可以直接将传入的数组长度和n做匹配:
你的测试代码中arr的类型是char const[3],取地址后类型是char const (*)[3],编译器可以直接推导出n = 3,匹配成功,所以可以正常编译。
补充说明
不是说带偏移的用法完全不能用,如果你主动显式指定模板参数,不需要编译器推导的话,代码是可以正常运行的,比如下面的写法是合法的:
test<2>(&arr); // 手动指定n=2,计算n+1=3和数组大小匹配,编译通过
内容的提问来源于stack exchange,提问作者user541686
相关产品推荐
相关产品推荐

