对 std::array 的引用大小在编译时不可用
Size of reference to std::array not available at compiletime
我很想知道为什么下面代码中的第二个 static_assert
不起作用。似乎即使数组 c
是对 a
的引用,数组的大小也嵌入到类型中,因此它应该在编译时可用。
#include <array>
int main()
{
std::array<int,2> a = {1,2};
std::array<int,2> b = {2,3};
std::array<int,2>& c = a;
static_assert(a.size() == b.size(), "a.size==b.size"); // ok size of array is compile time constant
static_assert(c.size() == a.size(), "c.size==a.size"); // compiler error "static_assert expression is not an integral constant expression"
}
请注意,如果将所有声明移出 main 函数,代码将会编译。为什么?因为 a
是自动变量,所以它不是真正的编译时对象并且这里没有省略引用,因此 a
和 c
或 c.size()
都不是 constexpr
.对于 a
的全局变量位置可以在编译时确定。
如果您尝试像这样在函数中绑定它们:
constexpr std::array<int,2> a = {1,2};
std::array<int,2> b = {2,3};
constexpr const std::array<int,2>& c = a;
你会得到错误提示 a
不是常量表达式。仍然可以编译的变体:
#include <array>
std::array<int,2> a = {1,2};
std::array<int,2> b = {2,3};
int main()
{
std::array<int,2>& c = a;
static_assert(a.size() == b.size(), "a.size==b.size");
static_assert(c.size() == a.size(), "c.size==a.size");
}
the size of the array is embedded in the type, so it should be available at compile time.
这是事实。但无论如何,c
不是常量表达式,因此包含它作为子表达式的表达式不能是常量表达式 - 除了某些仅与操作数类型交互的运算符,例如 sizeof
.
例如,您可以使用以下方法获取尺寸:
static_assert(
std::tuple_size<
std::remove_reference_t<decltype(c)>
>::value == a.size(),
"c.size==a.size"
);
遗憾的是,它不是很漂亮。
我很想知道为什么下面代码中的第二个 static_assert
不起作用。似乎即使数组 c
是对 a
的引用,数组的大小也嵌入到类型中,因此它应该在编译时可用。
#include <array>
int main()
{
std::array<int,2> a = {1,2};
std::array<int,2> b = {2,3};
std::array<int,2>& c = a;
static_assert(a.size() == b.size(), "a.size==b.size"); // ok size of array is compile time constant
static_assert(c.size() == a.size(), "c.size==a.size"); // compiler error "static_assert expression is not an integral constant expression"
}
请注意,如果将所有声明移出 main 函数,代码将会编译。为什么?因为 a
是自动变量,所以它不是真正的编译时对象并且这里没有省略引用,因此 a
和 c
或 c.size()
都不是 constexpr
.对于 a
的全局变量位置可以在编译时确定。
如果您尝试像这样在函数中绑定它们:
constexpr std::array<int,2> a = {1,2};
std::array<int,2> b = {2,3};
constexpr const std::array<int,2>& c = a;
你会得到错误提示 a
不是常量表达式。仍然可以编译的变体:
#include <array>
std::array<int,2> a = {1,2};
std::array<int,2> b = {2,3};
int main()
{
std::array<int,2>& c = a;
static_assert(a.size() == b.size(), "a.size==b.size");
static_assert(c.size() == a.size(), "c.size==a.size");
}
the size of the array is embedded in the type, so it should be available at compile time.
这是事实。但无论如何,c
不是常量表达式,因此包含它作为子表达式的表达式不能是常量表达式 - 除了某些仅与操作数类型交互的运算符,例如 sizeof
.
例如,您可以使用以下方法获取尺寸:
static_assert(
std::tuple_size<
std::remove_reference_t<decltype(c)>
>::value == a.size(),
"c.size==a.size"
);
遗憾的是,它不是很漂亮。