mingw-w64 / mingw-w64.github.io

mingw-w64.net web page contents (The new web page)
Other
599 stars 1.34k forks source link

The msvc compiler compiled successfully, but the mingw compiler failed #53

Closed wangyuou closed 5 months ago

wangyuou commented 5 months ago
#include <any>
#include <map>
#include <string>
struct AddressData
{
public:
    std::any value2;

    AddressData(std::any value2) : value2(std::move(value2)) {}

    AddressData() {}
    ~AddressData()
    {
    }

    AddressData(const AddressData &other)
        : value2(other.value2)
    {
    }

    AddressData &operator=(const AddressData &other)
    {
        if (this != &other)
        {
            value2 = other.value2;
        }
        return *this;
    }

    AddressData(AddressData&&) = default;
    AddressData& operator=(AddressData&&) = default;
};

int main(int argc, char *argv[])
{
    std::map<int,AddressData> map;
    map.insert(std::make_pair(1,AddressData(std::string())));
    map.insert(std::make_pair(2,AddressData(20)));
}

The error message is as follows:

D:\software\qt\Tools\mingw1120_64\lib\gcc\x86_64-w64-mingw32\11.2.0\include\c++\type_traits:935: error: invalid use of incomplete type 'struct std::is_constructible_impl<AddressData, const AddressData&>' C:/Users/Administrator/Documents/untitled6/main.cpp:39:15: required from here D:/software/qt/Tools/mingw1120_64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/type_traits:935:12: error: invalid use of incomplete type 'struct std::is_constructible_impl<AddressData, const AddressData&>' 935 | struct is_copy_constructible_impl<_Tp, true> | ^~~~~~~~~~~ D:/software/qt/Tools/mingw1120_64/lib/gcc/x86_64-w64-mingw32/11.2.0/include/c++/type_traits:905:12: note: declaration of 'struct std::is_constructible_impl<AddressData, const AddressData&>' 905 | struct __is_constructible_impl | ^~~~~~~

hello ! Is this a compiler bug? please tell me how to fix it. thanks

lhmouse commented 5 months ago

This looks like a bug in GCC 11, and has been fixed in GCC 13: https://gcc.godbolt.org/z/74f9Eobnh

A workaround would be to replace

    AddressData(std::any value2) : value2(std::move(value2)) {}

with

    template<typename T,
    // disable if `T` is same as `AddressData` or derives from `AddressData`
    std::enable_if_t<!std::is_base_of_v<AddressData, std::decay_t<T>>>* = nullptr>
    AddressData(T&& value2) : value2(std::forward<T>(value2)) {}
wangyuou commented 5 months ago

Okay, thank you.