gpt4 book ai didi

c++ - 通用引用和打包字段

转载 作者:太空狗 更新时间:2023-10-29 21:09:58 27 4
gpt4 key购买 nike

考虑以下代码:

#include <cstdint>

struct S {
uint32_t f1;
} __attribute__((packed)); // removing this attribute makes things work.

template <class T> void func(const T &x) {}
template <class T> void func(T &&x) {} // commenting out this line makes it "work"

int main() {
S s;
func(s.f1); // Error here in GCC, but not clang
}

GCC 给出以下错误:

<source>: In function 'int main()':
<source>:16:12: error: cannot bind packed field 's.S::f1' to 'unsigned int&'
16 | func(s.f1);
| ~~^~

GCC 似乎选择不允许对打包结构的成员进行通用引用,这可能是出于对齐问题。但是,clang 可以很好地编译代码。

让我更加困惑的是,如果我删除 (T &&x) 重载,如果只有 (const T &) 重载存在,它就“很好”地工作。我希望如果它不能使用 universal-ref 重载,那么它只会退回到 const-ref 版本......但它没有。

这里clang不正确吗?是海湾合作委员会吗?这只是未定义的行为,因此它们都是“正确的”吗?

最佳答案

func(const T &x) 是允许的,因为 GCC 将创建一个临时的打包成员。

添加转发引用重载时,函数调用将解析为类似于func(uint32_t&) 的函数。由于它是可变左值引用,因此无法创建临时对象并且重载解析失败,因为没有更好的匹配。

您可以通过强制 const 允许编译器再次创建临时变量来使其工作:

func(std::as_const(s).f1);

关于c++ - 通用引用和打包字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56428618/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com