0

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

ellipsis
  • 155
  • 1
  • 5
  • 1
    Compiler-deducted arguments is a C++14 feature. GCC version 6 have a complete C++14 implementation (and most of the upcoming C++17 standard as well). VC++ 2015 (as usual) lags behind and does not have the full C++14 standard implemented. – Some programmer dude Sep 16 '16 at 21:21
  • It seems so. But here http://en.cppreference.com/w/cpp/compiler_support stated that generic lambda is supported by msvc14 – ellipsis Sep 16 '16 at 21:27
  • 1
    Okay, VC++ support generic lambdas, but after reading a little more (especially the error message you have) it's not the lambda that is the problem, but the type-deduction of the argument to the `make_cond_functor` function. That seems to be a GCC extension. It seems to have been part of the concepts proposal, but that haven't made it into any standard yet. – Some programmer dude Sep 16 '16 at 21:33
  • You're right. Thanks for your response. – ellipsis Sep 17 '16 at 07:08

1 Answers1

1

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.

xinaiz
  • 7,744
  • 6
  • 34
  • 78
  • Actually, it [has been proposed](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4040.pdf) for C++17. – paulotorrens Sep 16 '16 at 23:15
  • Yeah. make_cond_functor is abbreviated function. And it's even not in c++17. see: http://en.cppreference.com/w/cpp/language/function Also: http://stackoverflow.com/questions/34918814/abbreviated-function-template-vs-function-template-with-forwarding-reference-pa – ellipsis Sep 17 '16 at 04:35
  • 1
    @PauloTorrens for C++20, as far as I know C++17 was finalized and auto parameters was not added. – Yakk - Adam Nevraumont Sep 17 '16 at 22:51
  • 2
    So I'll have to wait five more years to use this portably in my code? I don't even want to live that long. :( – paulotorrens Sep 17 '16 at 23:47