Home > Back-end >  msvc and fold expression
msvc and fold expression

Time:09-17

I'm having trouble compiling this code on Windows.

This code compile correctly on Linux, both with clang and gcc. I'm using msvc 19.29.

Msvc exit with the not so helpful error C1001.

struct Object{};

class Storage {
    Object &createObject() {
        qStorrage.push_back(Object{});
        return qStorrage.back();
    }

    template <class... Objs>
    void deleteObject(const Objs&...obj)
    {
        const auto e = std::remove_if(qStorrage.begin(), qStorrage.end(), [&](const auto &i) { return ((i == obj) || ...); });
        qStorrage.erase(e, qStorrage.end());
    }
}

The goal is to be able to pass multiple reference of Object to be deleted, to avoid calling multiple time the same function.

Storage stor;

auto a = stor.create();
auto b = stor.create();

stor.delete(a, b);

Do you know why MSVC fail to compile this ?

EDIT :

Here is the actual files:

https://github.com/zcorniere/logger-cpp/blob/windows/include/Logger.hpp

https://github.com/zcorniere/logger-cpp/blob/windows/example/example.cpp

build with cmake with parameter BUILD_EXAMPLE turned ON

EDIT2: Here is msvc error message, sorry I forgot about it

message : This diagnostic occurred in the compiler generated function 'bool ProgressBar::operator ==(const ProgressBar &) const' [C:\Users\Zacharie Corniere\Documents\GitHub\logger-cpp\build\example\example.vcxproj]
[build] C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\xmemory(1967): message : see reference to function template instantiation 'bool Logger::deleteProgressBar::<lambda_1>::operator ()<ProgressBar>(const _T1 &) const' being compiled [logger-cpp\build\example\example.vcxproj]
[build]           with
[build]           [
[build]               _T1=ProgressBar
[build]           ]
[build] logger-cpp\include\Logger.hpp(51): message : see reference to function template instantiation '_FwdIt std::remove_if<std::_Deque_iterator<std::_Deque_val<std::_Deque_simple_types<_Ty>>>,Logger::deleteProgressBar::<lambda_1>>(_FwdIt,const _FwdIt,_Pr)' being compiled [logger-cpp\build\example\example.vcxproj]
[build]           with
[build]           [
[build]               _FwdIt=std::_Deque_iterator<std::_Deque_val<std::_Deque_simple_types<ProgressBar>>>,
[build]               _Ty=ProgressBar,
[build]               _Pr=Logger::deleteProgressBar::<lambda_1>
[build]           ]

CodePudding user response:

C1001 is Internal Compiler Error.

It is used to indicate bugs in the compiler itself, the code being compiled is not necessarily wrong.

Report ICE to https://developercommunity.visualstudio.com/ or via Help > Send Feedback > Report a problem... from Visual Studio

Try to reduce what exactly produces ICE. This will help both making a good error report and avoiding ICE in your code, as a fix may not be available soon.


I've reduced your example:

#include <vector>

class ProgressBar
{
public:
    std::strong_ordering operator<=>(const ProgressBar &) const = default;
};

std::vector<ProgressBar> v;

    template <class... Objs>
    void deleteObject(const Objs&...obj)
    {
        std::remove_if(v.begin(), v.end(), [&](const auto &i) { return ((i == obj) || ...); });
    }

int main()
{
    ProgressBar p;
    deleteObject(p);
} 

See recreated error message: https://godbolt.org/z/dbz34PcTf

and I've reported it: https://developercommunity.visualstudio.com/t/internal-compiler-error-with-fold-expression-and-d/1522072


Workaround

In addition to <=> operator add == operator to ProgressBar:

    std::strong_ordering operator<=>(const ProgressBar &) const = default;
    bool operator==(const ProgressBar &) const = default;

CodePudding user response:

It will not compile, because delete is a reserved keyword. Change the 'd' to 'D'.

You also need to add a semicolon at the end of the struct definition.

And you need to declare the qStorrage member (like std::vector<Object> qStorrage;).

  • Related