FunctionalPlus: Compile error when using transparent function objects

Hello, awesome lib! I was playing a bit with it and I have the following example code that compiles and runs as expected:

#include <iostream>
#include <vector>
#include <string>

#include <fplus/fplus.hpp>

using namespace std::string_literals;

int main()
{
  auto const l1 = {"Hello"s, "World"s};
  auto const l2 = {","s, "!"s};
  auto const v = fplus::zip_with(std::plus<std::string>{}, l1, l2);
  std::cout << fplus::show_cont_with(" ", v) << std::endl;
}

However, when I use std::plus<>{}, I get a compiler error (VS2017 on Win10 x64):

include\fplus/function_traits.hpp(79): error C3556: ‘std::plus<void>::operator ()’: incorrect argument to ‘decltype’ include\fplus/pairs.hpp(42): note: see reference to class template instantiation ‘utils::function_traits<F>’ being compiled C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.10.25017\include\chrono(227): note: see reference to class template instantiation ‘std::chrono::duration<__int64,std::nano>’ being compiled C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.10.25017\include\chrono(1002): note: see reference to class template instantiation ‘std::chrono::time_pointstd::chrono::steady_clock,std::chrono::steady_clock::duration’ being compiled include\fplus/function_traits.hpp(80): error C2955: ‘utils::function_traits’: use of class template requires template argument list include\fplus/function_traits.hpp(79): note: see declaration of ‘utils::function_traits’ include\fplus/pairs.hpp(42): error C2039: ‘arity’: is not a member of ‘utils::function_traits<F>’ include\fplus/pairs.hpp(42): note: see declaration of ‘utils::function_traits<F>’ include\fplus/pairs.hpp(42): error C2065: ‘arity’: undeclared identifier include\fplus/pairs.hpp(45): error C2903: ‘arg’: symbol is neither a class template nor a function template include\fplus/pairs.hpp(45): error C2039: ‘type’: is not a member of ‘utils::function_traits<F>’ include\fplus/pairs.hpp(42): note: see declaration of ‘utils::function_traits<F>’ include\fplus/pairs.hpp(45): warning C4091: 'typedef ': ignored on left of ‘int’ when no variable is declared include\fplus/pairs.hpp(45): error C2144: syntax error: ‘unknown-type’ should be preceded by ‘;’ include\fplus/pairs.hpp(46): error C2903: ‘arg’: symbol is neither a class template nor a function template include\fplus/pairs.hpp(46): error C2039: ‘type’: is not a member of ‘utils::function_traits<F>’ include\fplus/pairs.hpp(42): note: see declaration of ‘utils::function_traits<F>’ include\fplus/pairs.hpp(46): warning C4091: 'typedef ': ignored on left of ‘int’ when no variable is declared include\fplus/pairs.hpp(46): error C2144: syntax error: ‘unknown-type’ should be preceded by ‘;’ include\fplus/pairs.hpp(49): error C2923: ‘std::is_convertible’: ‘FIn0’ is not a valid template type argument for parameter ‘_To’ include\fplus/pairs.hpp(45): note: see declaration of ‘FIn0’ include\fplus/pairs.hpp(49): error C2955: ‘std::is_convertible’: use of class template requires template argument list C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.10.25017\include\type_traits(416): note: see declaration of ‘std::is_convertible’ include\fplus/pairs.hpp(50): error C2057: expected constant expression include\fplus/pairs.hpp(51): error C2923: ‘std::is_convertible’: ‘FIn1’ is not a valid template type argument for parameter ‘_To’ include\fplus/pairs.hpp(46): note: see declaration of ‘FIn1’ include\fplus/pairs.hpp(51): error C2955: ‘std::is_convertible’: use of class template requires template argument list C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.10.25017\include\type_traits(416): note: see declaration of ‘std::is_convertible’ include\fplus/pairs.hpp(52): error C2057: expected constant expression

I never really used transparent function objects, so it might very well be a silly mistake.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 35 (17 by maintainers)

Commits related to this issue

Most upvoted comments

I was playing around yesterday, and after refactoring my POC I stumbled on the compiler error you mentioned in test_tree.cpp.

It is because I only handled &F::operator(), which only works for function objects. I was thinking about putting is_invocable/invoke et al. in the library to help with this, which can be implemented in C++11.

You might want to replace result_of with invoke_result later on, the former has been deprecated in C++17, and the Notes on cppreference are quite scary.

I will also need to workaround the template arguments that rely on result_of. The issue is that those are used to determine the return type of the function. Right now, I use a fallback to return a invalid_call_t type when result_of cannot retrieve a Callable return type, that way I am able to trigger static_asserts in the body of zip_with.

Without this workaround, none of the static_asserts are triggered, which is quite inconvenient.

I think I might be able to open a PR before the end of the week, which will only handle zip_with. If you approve the changes, I will do the other functions as well 😃

I believe this is has been superseded by the trigger_static_asserts facility.

I will see if it can be removed once I finish converting the library.

Perfect, it shouldn’t take that long to implement