Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
192 views
in Technique[技术] by (71.8m points)

c++ - Compiling Kevlin Henney's Fizzbuzz with the use of lambdas in C++17 using Visual Studio 2017's compiler

I was following Kevlin Henney's Youtube video on Lambdas in programming. At about 20:30 - 20:40 in his video he gives this code snippet:

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));
}

Here is my actual code within my 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) << '
';
    return 0;
}

However, when I try to compile this Visual Studio is generating these compiler errors:

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 ==========

When I check this against CompilerExplorer found here, This code compiles with all three of the major compilers: GCC, Clang, and MSVC...

I know that C++17 supports both lambdas and std::function<T>, but is this type of implementation or usage specific to a newer version of the compiler? Meaning is this technique or usage only available with say C++20 and later? If so, what can be done to this code snippet so that it can be compiled under Visual Studio 2017 using C++17 that will provide the same semantics and behavior?


Edit

Here are all of my Compiler's Command-Line Settings in regards to the C/C++ Language section:

/JMC /permissive- /GS /W3 /Zc:wchar_t /Qspectre /ZI /Gm- /Od /sdl /Fd"x64Debugvc141.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"x64Debug" /EHsc /nologo /Fo"x64Debug" /Fp"x64DebugData Structure Samples.pch" /diagnostics:classic

question from:https://stackoverflow.com/questions/65895753/compiling-kevlin-henneys-fizzbuzz-with-the-use-of-lambdas-in-c17-using-visual

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It is a bug; a?b:c is legal if b can be converted to an rvalue of type c and not vice versa (among other rules).

To fix:

auto fizz = [=](std::function<std::string(std::string)> f) {
    if(n%3 == 0)
      f = [=](auto) { return "Fizz" + f(""); };
    return f;
};
auto buzz = [=](std::function<std::string(std::string)> f) {
    if(n % 5 == 0)
      f = [=](auto) { return "Buzz" + f(""); };
    return f;
};

that should work.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...