模板 – C:为什么这个constexpr不是编译时常数

发布时间:2020-01-06 发布网站:大佬教程
大佬教程收集整理的这篇文章主要介绍了模板 – C:为什么这个constexpr不是编译时常数大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
在以下C 11代码中,最后一次调用arraySize会导致编译错误.显然这是因为y是一个运行时大小的数组,并且arraySize模板参数N不能被推导出来.我不明白为什么x是一个编译时间大小的数组,但是y结束运行时大小. arraySize模板函数直接从Scott Meyers的“有效现代C”项目1中获取.
#include <cstddef>

template<typename T,std::size_t N>
constexpr std::size_t arraySize(T(&)[N]) noexcept { return N; }

struct S
{
    char c[10];
};

int main()
{
    S s;
    S* ps = &s;

    char x[arraySize(s.c)];
    char y[arraySize(ps->c)]; // why is y a runtime sized array?

    arraySize(x);
    arraySize(y); // error !?

    return 0;
}

解决方法

在C中,错误不是调用arraySize(y),而是声明y本身.

数组声明中的边界必须是“转换的常量表达式”.

如果你的编译器接受y的声明,后来告诉你y是运行时绑定的数组,它不是一个C编译器. C的任何批准版本中没有运行时间限制的数组,也没有当前的草案.

arraySize(sc)和arraySize(ps-> c)之间的显着差异在于ps-> c与(* ps).c相同,* dereference操作符需要在ps上进行lvalue-to-rvalue转换,不是一个恒定的表达(也不是& s,见下文).表达式的其余部分不涉及到lvalue-to-rvalue转换,数组lvalue直接由引用绑定.

显然,ps包含具有自动存储持续时间的对象的地址,因此它不能被声明为constexpr.但是如果你改变S,一切都应该开始工作S * ps =& s;静态S; constexpr S * ps =& s;

(另一方面,你会认为arraySize(s.c)的参数也不是一个常量表达式,因为它是一个引用,而不是静态存储持续时间的对象)

大佬总结

以上是大佬教程为你收集整理的模板 – C:为什么这个constexpr不是编译时常数全部内容,希望文章能够帮你解决模板 – C:为什么这个constexpr不是编译时常数所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ群:277859234,请注明来意。