小编Nee*_*ahn的帖子

容器中过度对齐的结构和枚举之间的C ++差异

在C ++中,至少在GCC和Clang上,嵌入在容器(std :: vector)中的超对齐类型似乎被不同地对待,具体取决于该类型是超对齐结构还是超对齐枚举。对于struct版本,每个元素都对齐,而对于枚举,只有整个缓冲区具有指定的对齐方式。该行为是否由标准指定?如果是这样,哪一部分提到了?还是实现定义的,不应该依赖?

考虑以下:

#include<cstdint>
#include<iostream>
#include<vector>

struct alignas(16) byte_struct {std::uint8_t value;};
enum alignas(16) byte_enum : std::uint8_t {};

int main() {
    {//with struct
        std::vector<byte_struct> bytes;
        bytes.push_back(byte_struct{1});
        bytes.push_back(byte_struct{2});
        bytes.push_back(byte_struct{3});
        for(auto it = bytes.begin(); it!= bytes.end(); ++it) {
                std::cout<<&*it<<std::endl;
        }
    }
    {//with enum
        std::vector<byte_enum> bytes;
        bytes.push_back(byte_enum{1});
        bytes.push_back(byte_enum{2});
        bytes.push_back(byte_enum{3});
        for(auto it = bytes.begin(); it!= bytes.end(); ++it) {
                std::cout<<&*it<<std::endl;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

具有过度对齐的结构的版本将打印以下内容

0x10a9ec0 0x10a9ed0 0x10a9ee0

带有过度对齐的枚举的版本将打印以下内容

0x10a9e70 0x10a9e71 0x10a9e72

在向量存储区中,每个byte_struct都对齐到16个字节的边界,而byte_enum的对齐方式只适用于整个缓冲区,而不适用于每个单独的元素。

在GCC 9.1和Clang 8.0上,此行为相同,而MSVC 19.20遇到内部编译器错误。

编译器资源管理器的链接为:https : //godbolt.org/z/GUg2ft

c++ memory-alignment language-lawyer c++17

8
推荐指数
1
解决办法
165
查看次数

具有可变参数包的函数的C ++部分模板参数推导会在Clang和MSVC中产生歧义调用

考虑以下代码段(可在编译器epxlorer获得):

template<typename T, typename... Args>
auto foo(Args&&... args) {}

template<typename... Args>
auto foo(Args&&... args) {}

int main() {
    foo<char>('a');
}
Run Code Online (Sandbox Code Playgroud)

对于GCC而言,它可以完美编译,而对于Clang和MSVC而言,则均无法编译(编译器表示模棱两可的调用

为什么Clang和MSVC无法如此看似明显的演绎?

编辑:GCC作为用户为我提供了预期的解决方案,是否有一种简单的方法来推动clang和msvc选择模板,而无需对原始代码进行太多更改?

c++ templates ambiguous-call variadic-templates

5
推荐指数
2
解决办法
77
查看次数