问题描述
鉴于 std :: array< T,N> :: size
是constexpr,在下面的代码段中
Given that std::array<T,N>::size
is constexpr, in the snippet below
-
Foo1 :: u
不是static
成员为什么重要?该类型在编译时是已知的,因此它的size()
也是如此. -
Foo2 :: bigger()
有什么问题?
- Why does it matter that
Foo1::u
is not astatic
member? The type is known at compile time and so is itssize()
. - What's wrong with
Foo2::bigger()
?
列表:
// x86-64 gcc 10.1
// -O3 --std=c++20 -pedantic -Wall -Werror
#include <array>
#include <cstdint>
union MyUnion {
std::array<uint8_t,32> bytes;
std::array<uint32_t,8> words;
};
struct Foo1 {
MyUnion u;
static constexpr size_t length {u.bytes.size()};
//invalid use of non-static data member 'Foo1::u'
};
struct Foo2 {
MyUnion u;
size_t x;
consteval int8_t length() const { return u.bytes.size(); };
bool bigger() const { return x > length(); }
//'this' is not a constant expression
};
我想在 MyUnion
声明中保留std :: array的长度,而不要求助于
I would like to keep std::array length in MyUnion
declaration and not resort to
constexpr size_t LEN {32};
union MyUnion {
std::array<uint8_t,LEN> bytes;
std::array<uint32_t,LEN/4> words;
};
推荐答案
这些情况有些不同.
在第一个中:
static constexpr size_t length {u.bytes.size()};
//invalid use of non-static data member 'Foo1::u'
您正在尝试访问没有对象的非静态数据成员.那不是你能做的.该表达式需要 some Foo1
.在非静态成员函数的上下文中,它隐式为 this-> u
,但是那里仍然需要一些对象.仅有一个例外:您可以编写 sizeof(Foo1 :: u)
.
You're trying to access a non-static data member without an object. That's just not a thing you can do. There needs to be some Foo1
associated with this expression. In the context of a non-static member function, it'd implicitly be this->u
, but there still needs to be some object there. There's only one exception: you're allowed to write sizeof(Foo1::u)
.
在第二个中:
consteval int8_t length() const { return u.bytes.size(); };
在这里, this
指针本身不是常量表达式(我们不知道它指向的是什么),因此通过它访问任何内容都会失败.这是使用未知引用的更广泛的常量表达式的一部分,其使用方式不会真正影响表达式的常量性(请参阅我的博客文章,网址为 constexpr数组大小问题).我最近写了一篇关于该主题的论文 ,该论文主要侧重于参考文献,但 this
是最狭窄的扩展.
Here, the this
pointer is not itself a constant expression (we don't know what it points to), so accessing anything through it fails. This is part of a broader case of constant expressions using unknown references in a way that doesn't really affect the constant-ness of the expression (see my blog post on the constexpr array size problem). I recently wrote a paper on this topic which was focused primarily on references, but this
is a narrow extension on top of that.
无论哪种方式,目前都无法使用,因为一切都必须是常数.因此,您必须根据您的建议采取一些措施:分别公开您想要的常量.
Either way, for now this can't work either, because everything has to be a constant. So you'll have to resort to something along the lines of what you suggest: expose the constant you want separately.
这篇关于如何获取非静态std :: array成员的constexpr`.size()`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!