-1

I learned about 'sauto template parameters in the answer to this question. A coworker had informed me that they were supported on , but I seem to have been less than successful in my attempt to utilize this functionality. I've written this toy example to demonstrate my problem:

struct Foo {
  int mem;
};

template <auto T>
decltype(T(Foo{})) bar(const Foo& param)
{
  return T(param);
}

int func(const Foo& param) { return param.mem; }

int main() {
  Foo myFoo{ 13 };

  cout << bar<&func>(myFoo);
}

I believe this to be good code as it works fine on gcc In Visual Studio however I get this:

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

I've ensured that my "C++ Language Standard" set to: "ISO C++ Latest Draft Standard (/std:c++latest)" but that doesn't seem to solve the problem. Visual Studio will support the pre-auto template parameter code which requires I pass the function type along with the function as template arguments: template <typename R, R(*T)(const Foo&)> R bar(const Foo& param) But this doesn't match the elegance of the auto template parameter.

Is there a way that I can either help Visual Studio compile the auto template code or manage similar elegance while still compiling on ?

Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • I would believe, downvoter(s) don't like the fact that the question is unclear. Yes, from your example it seems like VS2017 doesn't support auto template non-type parameters. And no, SO is not an MSVC helpdesk and is very ill equipped for fixing that for you. – SergeyA Nov 06 '18 at 21:33
  • 2
    Sad... I've always felt asking about workarounds for specific compilers fell under the "Software tools commonly used by programmers; and is a practical, answerable problem that is unique to software development" section of [What topics can I ask about here?](https://stackoverflow.com/help/on-topic) – Jonathan Mee Nov 06 '18 at 21:45
  • @Evg `auto` is a template parameter type as of C++17: https://en.cppreference.com/w/cpp/language/template_argument_deduction#Deduction_from_a_type The only use of it I've found is to pass functions as template arguments, though there may be other uses. – Jonathan Mee Nov 06 '18 at 22:08
  • 1
    @JonathanMee: "*I've always felt asking about workarounds for specific compilers*" But you're not asking for a "workaround". You genuinely *don't know* if you need a workaround or not. That's what makes it a poor question. If you had asked, "hey, VS2017 doesn't support `auto` template parameters in the version I'm using; how can I achieve a similar effect without it?" that would have shown that you actually did research into what VS2017 does and does not support. – Nicol Bolas Nov 06 '18 at 22:45
  • @NicolBolas First let me say I appreciate that you've given me some direction on how to improve this. I think your key point is that: I don't know whether I need to help my compiler or work around this in code. Which gives the impression that I didn't try anything to find a solution. My question was primarily driven by the fact that I was assured by a coworker that Visual Studio 2017 did support `auto` template parameters, but I had independently validated that it did not. The research that I did went only as far as looking up the error code and validating that my code compiled on GCC. – Jonathan Mee Nov 07 '18 at 13:47
  • @NicolBolas I've tried to tailor the question to more aptly demonstrate the research I did in reaching the point of asking a question. I'm not certain if that improved things, but if you're feeling so inclined I would welcome any further constructive input that you may offer. – Jonathan Mee Nov 07 '18 at 13:48

2 Answers2

4

This MS help page states:

A method or template parameter cannot be declared with the auto keyword if the default /Zc:auto compiler option is in effect.

So you either turn off /Zc:auto or you can pass this function as parameter:

#include <iostream>

struct Foo {
    int mem;
};

int func(const Foo& param) {
    return param.mem;
}

template <class Func>
auto bar(const Foo& param, Func&& f) {
    return f(param);
}

int main() {
    Foo f { 42 }; 
    std::cout << bar(f, func);
}
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
mostsignificant
  • 312
  • 1
  • 8
  • This seems like an answer to OP's question, why wasn't it accepted/upvoted? – SergeyA Nov 06 '18 at 22:09
  • @SergeyA The OP is probably going to sulk a little while; and accept tomorrow. – Jonathan Mee Nov 06 '18 at 22:12
  • @JonathanMee I think such behavior is not in the spirit of SO. You have been given an answer, and it seems like a correct answer (I can't check, but it has link to help page explaining exactly your case) and yet you are not ready to accept it. – SergeyA Nov 06 '18 at 22:15
  • 2
    @SergeyA Sorry, sulking was a strong term. Probably made stronger by the fact that the members of SO have given me good cause for sulking today. I actually never accept anything the same day I post. I want to give everyone time to write answers. In this case I'm happy I did wait, cause it looks like [Evg actually wrote a really good answer to my question](https://stackoverflow.com/a/53180898/2642059). – Jonathan Mee Nov 06 '18 at 22:19
  • @SourceChris This is an excellent answer. I think pre 15.7.0 this is the best solution. I've gone ahead and upvoted... But it seems like just upgrading Visual Studio is a better solution than surrendering `auto` template parameters. So I'll probably accept [Evg's answer](https://stackoverflow.com/a/53180898/2642059) – Jonathan Mee Nov 06 '18 at 22:22
  • @JonathanMee okidoki, no problem – mostsignificant Nov 07 '18 at 22:34
  • 1
    I already mentioned this was a pretty excellent answer. I was surprised to see it coming from someone with so little reputation. I just wanted to exhort you to keep at it. http://www.stackoverflow.com can always use more great question answerers. I looked through your other answers and found this: https://stackoverflow.com/a/52525561/2642059 it is another really good answer, the exact one I would have recommended. The fact that it too would have been victim to downvoting is discouraging. It now has my +1. Keep up the good work! – Jonathan Mee Nov 08 '18 at 13:23
4

auto non-type template parameters were introduced only in VS 2017 version 15.7.0.

Templates that are designed to take any type as a non-type parameter can now use the auto keyword in the template parameter list. This allows instantiations to use any type instead of needing to determine and supply the type of template parameter at the point of instantiation.

Before that version they are not supported.

Evg
  • 25,259
  • 5
  • 41
  • 83