0

MSVC doesn't seem to appreciate the macro-based solution I was given here to wrap a function template in a function object.

The macro is

#define FUNCTORIZE(func) [](auto&&... val) \
noexcept(noexcept(func(std::forward<decltype(val)>(val)...))) -> decltype(auto) \
{return func(std::forward<decltype(val)>(val)...);}

to be used (for instance) like this

template <std::size_t N>
inline constexpr auto get = FUNCTORIZE(std::get<N>);

so that one obtains a function object that can be passed around like this

std::transform(v.begin(), v.end(), w.begin(), get<1>);

And all works well in GCC and Clang, but MSVC errors like this:

<source>(12): error C2760: syntax error: unexpected token 'identifier', expected ')'
<source>(18): note: see reference to variable template 'const auto get<1>' being compiled
Compiler returned: 2
  • Probably I'd just need to add some compiler flag (other than one specifying a newer standard than C++17)?
  • Would writing the macro differently help?
  • Can I get that macro working in C++17 with MSVC?
Enlico
  • 23,259
  • 6
  • 48
  • 102
  • 1
    What version of Visual Studio are you using? What is the language standard set to? Consider putting together a [mcve] that others could copy/paste/compile. – Retired Ninja Jul 05 '21 at 05:33
  • @RetiredNinja clicking on the last link will allow you to copy, paste, compile. Or just compile. – Enlico Jul 05 '21 at 05:36
  • 1
    Compiles correctly for me with Visual Studio 2019 16.10.3 with C++ standard set to /std:c++latest. Also asserts on the `std::transform` line with "cannot seek value-initialized vector iterator" https://godbolt.org/z/z59jbPEz7 – Retired Ninja Jul 05 '21 at 05:42
  • 1
    @TedLyngmo, corrected. It was an error I did when de-Rangev3-ifying the code. They work now on GCC and Clang. – Enlico Jul 05 '21 at 05:47
  • @RetiredNinja, I need C++17. – Enlico Jul 05 '21 at 05:47
  • You asked if you needed a compiler flag. I gave one. After the edit it runs correctly as well. – Retired Ninja Jul 05 '21 at 05:48
  • @RetiredNinja, sorry, I was imprecise. I've clarified in the question now. Anyway good to know that the problem is solved with /std:c++latest. – Enlico Jul 05 '21 at 05:53
  • cppinsights says "_INSIGHTS: Unexpected noexcept expr_" 3 times. Perhaps there's something there? – Ted Lyngmo Jul 05 '21 at 06:04
  • Why not just use `std::get` directly in `std::transform`? – Alan Birtles Jul 05 '21 at 06:07
  • @AlanBirtles, because you can't. `std::get` is still a templated function (templated on it's argument too), not a function object, so you can't pass its name around hoping that the argument deduction can be delayed. That's the whole point of the question I linked. – Enlico Jul 05 '21 at 06:08
  • 2
    If `noexcept` part is removed, MSVC accepts the code with `/std:c++17` – Igor Tandetnik Jul 05 '21 at 13:17
  • That's very interesting, @IgorTandetnik, thanks! – Enlico Jul 05 '21 at 13:31

0 Answers0