msvc 和折叠表达式
msvc and fold expression
我在 Windows 上编译此代码时遇到问题。
这段代码在 Linux 上可以通过 clang 和 gcc 正确编译。我正在使用 msvc 19.29.
Msvc 退出并出现不太有用的错误 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());
}
}
目标是能够传递Object
的多个引用被删除,避免多次调用同一个函数。
Storage stor;
auto a = stor.create();
auto b = stor.create();
stor.delete(a, b);
你知道为什么 MSVC 编译失败吗?
编辑:
这是实际的文件:
https://github.com/zcorniere/logger-cpp/blob/windows/include/Logger.hpp
https://github.com/zcorniere/logger-cpp/blob/windows/example/example.cpp
使用参数 BUILD_EXAMPLE 开启的 cmake 构建
编辑2:
这是 msvc 错误信息,抱歉我忘记了
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 Studio19\Community\VC\Tools\MSVC.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] ]
编译不通过,因为delete
是保留关键字。将 'd' 更改为 'D'。
您还需要在结构定义的末尾添加一个分号。
并且您需要声明 qStorrage 成员(如 std::vector<Object> qStorrage;
)。
C1001
是内部编译器错误。
用来表示编译器本身的bug,编译出来的代码不一定是错的。
向 https://developercommunity.visualstudio.com/ 或通过 帮助 > 发送反馈 > 报告问题... 来自 Visual Studio
报告 ICE
尝试减少确切产生 ICE 的物质。这将有助于生成良好的错误报告并避免代码中的 ICE,因为修复可能不会很快可用。
我已经减少了你的例子:
#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);
}
查看重新创建的错误消息:https://godbolt.org/z/dbz34PcTf
我已经举报了。
更新
根据 developer community feedback item,这是内部修复的,因此将在一段时间内提供预览版。
不过,我认为它会在 Visual Studio 2022 年发布,并且不会移植到 Visual Studio 2019 年。
解决方法
除了 <=>
运算符之外,将 ==
运算符添加到 ProgressBar
:
std::strong_ordering operator<=>(const ProgressBar &) const = default;
bool operator==(const ProgressBar &) const = default;
我在 Windows 上编译此代码时遇到问题。
这段代码在 Linux 上可以通过 clang 和 gcc 正确编译。我正在使用 msvc 19.29.
Msvc 退出并出现不太有用的错误 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());
}
}
目标是能够传递Object
的多个引用被删除,避免多次调用同一个函数。
Storage stor;
auto a = stor.create();
auto b = stor.create();
stor.delete(a, b);
你知道为什么 MSVC 编译失败吗?
编辑:
这是实际的文件:
https://github.com/zcorniere/logger-cpp/blob/windows/include/Logger.hpp
https://github.com/zcorniere/logger-cpp/blob/windows/example/example.cpp
使用参数 BUILD_EXAMPLE 开启的 cmake 构建
编辑2: 这是 msvc 错误信息,抱歉我忘记了
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 Studio19\Community\VC\Tools\MSVC.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] ]
编译不通过,因为delete
是保留关键字。将 'd' 更改为 'D'。
您还需要在结构定义的末尾添加一个分号。
并且您需要声明 qStorrage 成员(如 std::vector<Object> qStorrage;
)。
C1001
是内部编译器错误。
用来表示编译器本身的bug,编译出来的代码不一定是错的。
向 https://developercommunity.visualstudio.com/ 或通过 帮助 > 发送反馈 > 报告问题... 来自 Visual Studio
报告 ICE尝试减少确切产生 ICE 的物质。这将有助于生成良好的错误报告并避免代码中的 ICE,因为修复可能不会很快可用。
我已经减少了你的例子:
#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);
}
查看重新创建的错误消息:https://godbolt.org/z/dbz34PcTf
我已经举报了。
更新
根据 developer community feedback item,这是内部修复的,因此将在一段时间内提供预览版。
不过,我认为它会在 Visual Studio 2022 年发布,并且不会移植到 Visual Studio 2019 年。
解决方法
除了 <=>
运算符之外,将 ==
运算符添加到 ProgressBar
:
std::strong_ordering operator<=>(const ProgressBar &) const = default;
bool operator==(const ProgressBar &) const = default;