【发布时间】:2021-01-26 04:05:45
【问题描述】:
我在 Lambdas 上关注 Kevlin Henney's Youtube video 进行编程。在大约 20:30 - 20:40 在他的视频中,他给出了这个代码 sn-p:
string fizzbuzz(int n)
{
auto fizz = [=](function<string(string)> f)
{
return n % 3 == 0 ? [=](auto) {return "Fizz" + f("");} : f;
};
auto buzz = [=](function<string(string)> f)
{
return n % 5 == 0 ? [=](auto) {return "Buzz" + f("");} : f;
};
auto id = [](auto s) { return s; };
return fizz(buzz(id))(to_string(n));
}
这是我在 IDE 中的实际代码:
#include <functional>
#include <iostream>
#include <string>
std::string fizzbuzz(int n) {
auto fizz = [=](std::function<std::string(std::string)> f) {
return n % 3 == 0 ? [=](auto) { return "Fizz" + f(""); } : f;
};
auto buzz = [=](std::function<std::string(std::string)> f) {
return n % 5 == 0 ? [=](auto) { return "Buzz" + f(""); } : f;
};
auto id = [](auto s) { return s; };
return fizz(buzz(id))(std::to_string(n));
}
int main() {
for (int i = 1; i <= 100; i++)
std::cout << fizzbuzz(i) << '\n';
return 0;
}
但是,当我尝试编译此 Visual Studio 时,会生成以下编译器错误:
1>------ Build started: Project: Data Structure Samples, Configuration: Debug x64 ------
1>main.cpp
1>c:\...\main.cpp(62): error C2445: result type of conditional expression is ambiguous: types 'fizzbuzz::<lambda_9027e592dd51e6f4c5342b61ff8c23f0>::()::<lambda_2463463a8046fa170a40e78d59e9f461>' and 'std::function<std::string (std::string)>' can be converted to multiple common types
1>c:\...\main.cpp(62): note: could be 'fizzbuzz::<lambda_9027e592dd51e6f4c5342b61ff8c23f0>::()::<lambda_2463463a8046fa170a40e78d59e9f461>'
1>c:\...\main.cpp(62): note: or 'std::function<std::string (std::string)>'
1>c:\...\main.cpp(65): error C2445: result type of conditional expression is ambiguous: types 'fizzbuzz::<lambda_c18a2fee5ba13240be9b86f815911a7c>::()::<lambda_2774da13f447e3dfb583778d4ea6d5bd>' and 'std::function<std::string (std::string)>' can be converted to multiple common types
1>c:\...\main.cpp(65): note: could be 'fizzbuzz::<lambda_c18a2fee5ba13240be9b86f815911a7c>::()::<lambda_2774da13f447e3dfb583778d4ea6d5bd>'
1>c:\...\main.cpp(65): note: or 'std::function<std::string (std::string)>'
1>c:\...\main.cpp(68): error C2664: 'void fizzbuzz::<lambda_9027e592dd51e6f4c5342b61ff8c23f0>::operator ()(std::function<std::string (std::string)>) const': cannot convert argument 1 from 'void' to 'std::function<std::string (std::string)>'
1>c:\...\main.cpp(68): note: Expressions of type void cannot be converted to other types
1>Done building project "Data Structure Samples.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
当我对照 CompilerExplorer 进行检查时发现 here,此代码可使用所有三个主要编译器编译:GCC、Clang 和 MSVC...
我知道 C++17 支持lambdas 和std::function<T>,但是这种类型的实现或用法是否特定于较新版本的编译器?意思是这种技术或用法仅适用于 C++20 及更高版本吗?如果是这样,可以对这段代码 sn-p 做什么,以便它可以在 Visual Studio 2017 下使用提供相同语义和行为的 C++17 进行编译?
编辑
以下是我的编译器关于 C/C++ 语言部分的所有命令行设置:
/JMC /permissive- /GS /W3 /Zc:wchar_t /Qspectre /ZI /Gm- /Od /sdl /Fd"x64\Debug\vc141.pdb" /Zc:inline /fp:precise /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /std:c++latest /FC /Fa"x64\Debug\" /EHsc /nologo /Fo"x64\Debug\" /Fp"x64\Debug\Data Structure Samples.pch" /diagnostics:classic
【问题讨论】:
-
我不是在询问编译器错误,它们相当简单,我当前的编译器和设置抱怨参数不明确。我只是在找工作!
-
仅供参考:我的编译器语言标志设置为:
ISO C++ Latest Draft Standard (/std:c++latest)。似乎自动类型推导在这些 lambda 的上下文或它们的实现方式中不起作用...... -
从您所描述的设置来看,我看不出这应该失败的原因。从三元表达式推断返回类型似乎存在问题,因为一个分支返回
std::function而另一个返回 lambda。你的 Visual Studio 是什么版本? Compiler-Explorer 仅支持最旧的“2017 Update 9”,所以我想知道您是否使用的是具有推断错误的过时版本 -
15.9.24我认为应该足够新来支持这个... Compiler Explorer 上最旧的 MSVC 版本是v19.14我认为它应该对应于 Visual Studios 版本15.7.5,它接受此代码。不幸的是,我不确定为什么这不起作用。我唯一的猜测是当前语言版本的设置不正确(您所说的应该设置为/std:c++latest)。希望其他人能够捕捉到我没有看到的东西 -
我可能在older question 中发现了类似的问题。当时的 Visual Studios 2017 RC 似乎没有正确确定三元语句的结果表达式。我猜这是 MSVC 版本中的一个问题。不幸的是,MSVC 因没有按照规范正确实现 C++ 而臭名昭著
标签: c++ lambda compiler-errors visual-studio-2017 c++17