【问题标题】:alignas with pack expansion not working in Visual Studio 2019?alignas 与包扩展在 Visual Studio 2019 中不起作用?
【发布时间】:2023-03-29 20:20:01
【问题描述】:

我正在为 Variant 类编写一个简单的实现,但当我尝试实例化 AlignedStorage 类型的变量时,Visual Studio 拒绝了此代码:

using std::size_t;

template <size_t SIZE, size_t... ALIGNMENT>
struct AlignedStorage
{
    struct Type
    {
        alignas(ALIGNMENT...) unsigned char storage[SIZE];
    };
};

template <size_t SIZE, size_t... ALIGNMENT>
using AlignedStorageT = typename AlignedStorage<SIZE, ALIGNMENT...>::Type;

/**** variant storage class ****/
template <typename... Types>
class VariantStorage
{
public:
    void *GetStorage() { return mStorage.storage; }
    const void *GetStorage() const { return mStorage.storage; }

    template <typename T>
    T &GetStorageAs() { return *reinterpret_cast<T*>(GetStorage()); }
    template <typename T>
    const T &GetStorageAs() const { return *reinterpret_cast<const T*>(GetStorage()); }

    unsigned GetDiscriminator() const { return mDiscriminator; }
    void SetDiscriminator(unsigned discriminator) { mDiscriminator = discriminator; }

private:
    using LargestT = typename LargestType<Typelist<Types...>>::Type;
    AlignedStorageT<sizeof(LargestT), alignof(Types)...> mStorage;  ///////// Visual studio ERROR (not GCC)
    unsigned int mDiscriminator;  // discriminated union tag
};

ALIGNMENT 包扩展似乎有问题,Gcc 似乎工作正常,但它拒绝了另一行(VC++ 似乎没问题):

template <typename T, typename V>  // CRTP
class VariantChoice;

template <typename...>
class Variant;

template <typename Type, typename... Types>  
class VariantChoice<Type, Variant<Types...>>
{
friend class Variant<Types...>;  // private ctor

protected:  
    static constexpr unsigned int mDiscriminatorIndex = IndexOfType<Type, Typelist<Types...>>::Value;  // index of Type in typelist

private:
    VariantChoice() = default;

    ~VariantChoice() = default;

    VariantChoice(const VariantChoice &other);
    VariantChoice(VariantChoice &&other);

    VariantChoice &operator=(const VariantChoice &other);
    VariantChoice &operator=(VariantChoice &&other);

    using Derived = Variant<Types...>;    // CRTP 
    Derived &AsDerived() { return static_cast<Derived&>(*this); }
    const Derived &AsDerived() const { return static_cast<Derived const&>(*this); }
};

/**** variant class ****/
template <typename... Types>
class Variant : VariantStorage<Types...>, VariantChoice<Types, Variant<Types...>>...
{
template <typename, typename>
friend class VariantChoice;  // enable CRTP (private inheritance)

public:
    using VariantChoice<Types, Variant>::VariantChoice...;  // inherited ctors
    Variant() {}
    Variant(const Variant &other);
    Variant(Variant &&other);
    
    template <template <typename...> class Variant_, typename... Types_>
    Variant(Variant_<Types_...> &&other);
    
    using VariantChoice<Types, Variant>::operator=...;     ///////// GCC ERROR: bring copy/move assignment operators in scope doesn't compile ???? (VC++ works)
    Variant &operator=(Variant const &other);
    Variant &operator=(Variant &&other);

private:

}; 

这段代码正确吗?还是我在做一些不标准的事情?

编辑 我更正了 alignof(Types)...

【问题讨论】:

  • 不应该alignof(Types...)alignof(Types)...
  • 第一个错误似乎是MSVC中的bug,很简单。
  • @Quentin,不,alignas 应该能够使用包。按照你的方式尝试是行不通的。
  • @SergeyA 我的意思是alignof :)
  • @Quentin 但 OP 在对齐方面有问题?

标签: c++ templates variadic-templates compile-time-constant


【解决方案1】:

对于使用VariantChoice&lt;Types, Variant&gt;::operator=... 不适用于gcc 的问题,您应该将gcc 更新到至少gcc10,我使用ubuntu 和gcc9.3 并遇到了同样的问题。当我升级到gcc12 时,一切都很好。

【讨论】:

  • 我复制了你的程序并用gcc12编译,它是正确的。
猜你喜欢
  • 2021-08-30
  • 1970-01-01
  • 2020-06-03
  • 2021-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多