ellipsis ellipsis - 2 months ago 28
C++ Question

Generic lambda with msvc140

I don't undersatnd is there any problem with this code?

#include <iostream>
#include <string>
#include <type_traits>

bool condition_func(int x)
{
return x > 0;
}

std::string true_branch_func(int x)
{
return "true_branch_func(int x), x = " + std::to_string( x );
}

std::string false_branch_func(int x)
{
return "false_branch_func(int x), x = " + std::to_string(x);
}

// template<typename C, typename T, typename F>
auto make_cond_functor(auto && cond, auto && true_f, auto && false_f)
{
return [&](auto &&... args)
{
return cond(args...) ? true_f(args...) : false_f(args...);
};
}

int main()
{
std::cout << make_cond_functor(condition_func, true_branch_func, false_branch_func)(-3) << std::endl;
return 0;
}


In Visual Studio 2015 (msvc140) I have problem:


error C3533: a parameter cannot have a type that contains 'auto'

error C2664: 'make_cond_functor:: make_cond_functor(int &&,int &&,int &&)': cannot convert argument 1 from 'bool (__cdecl *)(int)' to 'int &&'

note: Reason: cannot convert from 'overloaded-function' to 'int'

note: There is no context in which this conversion is possible


But g++-6.2 compiles this code perfectly well. make_cond_functor returns generic lambda that allowed in c++14. So this code should be correct, shouldn't it? And there is problem with msvc140, not with code, right?

generic lambda at cppreference:enter link description here

Answer

MSVC is not at fault in this case (surprisingly). The problem is function make_cond_functor

auto make_cond_functor(auto && cond, auto && true_f, auto && false_f)
//                    /\            /\              /\
//                    NOT     VALID     C++     SYNTAX

This function signature is invalid. In current C++, the only case when you can use auto with function argument is generic lambda. This seems to be GCC extension introduced in GCC 4.9.0.