Mq-b / Loser-HomeWork

卢瑟们的作业展示,答案讲解,以及一些C++知识
https://mq-b.github.io/Loser-HomeWork/
Apache License 2.0
574 stars 128 forks source link

第3章-接口.md 中关于 MSVC 的问题已经在 VS 2022 17.10 Previews 1 中修复 #294

Closed frederick-vs-ja closed 5 months ago

frederick-vs-ja commented 5 months ago

参考

@Mq-b 我们应该考虑下这段如何重新组织:

事实上原书给的上面这段代码是有问题的,无法在 msvc 通过编译,这里使用的是 0 做初始值,有窄化转换,msvc 使用的是 {} 初始化。,检测到了,于是编译错误。(但是需要注意,不是简单的 {} 检测的问题,msvc 的实现和其他 stl 从根本上就不一样) 这里其实可以算作是 msvc 的 bug,这个场景需要良构 这里应该把 0 换成 Oull (基于当前 64 位环境),或者标准够高使用 0uz,再或者直接 std::size_t{0}

Mq-b commented 5 months ago

https://godbolt.org/ 更新有那么快吗?似乎没办法演示。 我手上没 VS2022 Preview 不知道它是不是已经更新了。

Mq-b commented 5 months ago

(但是需要注意,不是简单的 {} 检测的问题,msvc 的实现和其他 stl 从根本上就不一样)

这显然不对,人家还真就是只改了个初始化就行,没啥事。

Mq-b commented 5 months ago
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <execution>

int main(){
    std::vector<std::string>strVec{ "Only", "for", "testing", "purpose" };
    std::size_t res = std::transform_reduce(
        std::execution::par,
        strVec.begin(), strVec.end(),
        0,
        [](std::size_t a, std::size_t b) {return a + b; },
        [](std::string s) {return s.size(); }
    );
}

以上代码,更新到 VS2022 17.10 Preview 之后,可以通过编译,就是有一堆警告。

1>------ 已启动生成: 项目: Test, 配置: Debug x64 ------ 1>main.cpp 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\numeric(217,26): warning C4244: “=”: 从“unsigned int64”转换到“_Ty”,可能丢失数据 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\numeric(217,26): warning C4244: with 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\numeric(217,26): warning C4244: [ 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\numeric(217,26): warning C4244: _Ty=int 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\numeric(217,26): warning C4244: ] 1>(编译源文件“main.cpp”) 1> D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\numeric(217,26): 1> 模板实例化上下文(最早的实例化上下文)为 1> D:\project\Test\main.cpp(9,28): 1> 查看对正在编译的函数 模板 实例化“_Ty std::transform_reduce<const std::execution::parallel_policy&,std::_Vector_iterator<std::_Vector_val<std::_Simple_types<std::basic_string<char,std::char_traits,std::allocator>>>>,int,main::,main::,0>(_ExPo,const _FwdIt,const _FwdIt,_Ty,_BinOp,_UnaryOp) noexcept”的引用 1> with 1> [ 1> _Ty=int, 1> _ExPo=const std::execution::parallel_policy &, 1> _FwdIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types>>, 1> _BinOp=main::, 1> _UnaryOp=main:: 1> ] 1> D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4285,37): 1> 查看对正在编译的函数 模板 实例化“_Ty std::transform_reduce<_FwdIt,int,_Fn,main::>(const _InIt,const _InIt,_Ty,_BinOp,_UnaryOp)”的引用 1> with 1> [ 1> _Ty=int, 1> _FwdIt=std::basic_string<char,std::char_traits,std::allocator> , 1> _Fn=main::, 1> _InIt=std::basic_string<char,std::char_traits,std::allocator> , 1> _BinOp=main::, 1> _UnaryOp=main:: 1> ] 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4008,30): warning C4244: “=”: 从“unsigned int64”转换到“_Ty”,可能丢失数据 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4008,30): warning C4244: with 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4008,30): warning C4244: [ 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4008,30): warning C4244: _Ty=int 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4008,30): warning C4244: ] 1>(编译源文件“main.cpp”) 1> D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4008,30): 1> 模板实例化上下文(最早的实例化上下文)为 1> D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4291,24): 1> 查看对正在编译的函数 模板 实例化“_Ty std::_Reduce_move_unchecked<_Ty,int,_Fn>(_InIt,const _InIt,_Ty,_BinOp)”的引用 1> with 1> [ 1> _Ty=int, 1> _Fn=main::, 1> _InIt=int , 1> _BinOp=main:: 1> ] 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4239,22): warning C4244: “初始化”: 从“unsigned int64”转换到“_Ty”,可能丢失数据 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4239,22): warning C4244: with 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4239,22): warning C4244: [ 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4239,22): warning C4244: _Ty=int 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4239,22): warning C4244: ] 1>(编译源文件“main.cpp”) 1> D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4239,22): 1> 模板实例化上下文(最早的实例化上下文)为 1> D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4277,21): 1> 查看对正在编译的 类 模板 实例化“std::_Static_partitioned_transform_reduce2<std::basic_string<char,std::char_traits,std::allocator> ,int,_Fn,main::>”的引用 1> with 1> [ 1> _Fn=main:: 1> ] 1> D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4229,27): 1> 在编译 类 模板 成员函数“void std::_Static_partitioned_transform_reduce2<std::basic_string<char,std::char_traits,std::allocator> ,int,_Fn,main::>::_Threadpool_callback(std_PTP_CALLBACK_INSTANCE,void const ,__std_PTP_WORK) noexcept”时 1> with 1> [ 1> _Fn=main:: 1> ] 1> D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(184,20): 1> 请参阅 "std::_Work_ptr::_Work_ptr" 中对 "std::_Static_partitioned_transform_reduce2<std::basic_string<char,std::char_traits,std::allocator> ,int,_Fn,main::>::_Threadpool_callback" 的第一个引用 1> with 1> [ 1> _Fn=main:: 1> ] 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4241,34): warning C4244: “=”: 从“unsigned int64”转换到“_Ty”,可能丢失数据 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4241,34): warning C4244: with 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4241,34): warning C4244: [ 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4241,34): warning C4244: _Ty=int 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4241,34): warning C4244: ] 1>(编译源文件“main.cpp”) 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4248,38): warning C4244: “=”: 从“unsigned int64”转换到“_Ty”,可能丢失数据 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4248,38): warning C4244: with 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4248,38): warning C4244: [ 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4248,38): warning C4244: _Ty=int 1>D:\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.40.33521\include\execution(4248,38): warning C4244: ] 1>(编译源文件“main.cpp”) 1>Test.vcxproj -> D:\project\Test\x64\Debug\Test.exe 1>已完成生成项目“Test.vcxproj”的操作。 ========== 生成: 1 成功,0 失败,0 最新,0 已跳过 ========== ========== 生成 于 13:08 完成,耗时 02.315 秒 ==========

rsp4jack commented 5 months ago

这个警告应该是正常行为吧,初始值那里写了个 0 (int)

Mq-b commented 5 months ago

这个警告应该是正常行为吧,初始值那里写了个 0 (int)

正常是正常,msvc 目前没有实现 uz 字面量,好的写法只能是 std::size_t{0} 了。不过这和目前的问题无关倒是,标准要求支持 0 那种调用,而不是编译失败,目前是正确行为。

Mq-b commented 5 months ago

@frederick-vs-ja 聚聚有空提个 pr 改一下说辞吧。