Search code examples
c++templatesvisual-c++visual-studio-2017

How to solve MSVC treatment of C++ function templates that is different than that of GCC/Clang (unrecognizable template definition)?


A template helper function exists

#include <iostream>

namespace helpers {

  template <typename OUT = float, typename IN>
  OUT normalizeFromRange(IN v, IN min, IN max) {
    return static_cast<OUT>(v - min) / static_cast<OUT>(max - min);
  }

}

int main()
{
    float resultFAuto = helpers::normalizeFromRange<>(10, 0, 40);
    float resultF = helpers::normalizeFromRange<float>(20, 0, 40);
    double resultD = helpers::normalizeFromRange<double>(30, 0, 40);

    std::cout << "resultFAuto: " << resultFAuto << std::endl;
    std::cout << "resultF: " << resultF << std::endl;
    std::cout << "resultD: " << resultD << std::endl;

    return 0;
}

results in

resultFAuto: 0.25
resultF: 0.5
resultD: 0.75

It compiles on Clang, GCC, which are compilers I use. C++14. I want to build the project also on MSVC++ and it compiles on online MSVC++ compiler that claims to be using 19.00.23506

But it fails on my machine that uses 19.16.27027.1, C++14 set.

Microsoft Visual Studio Community 2017 
Version 15.9.9
VisualStudio.15.Release/15.9.9+28307.518
Installed Version: Community
Microsoft Visual C++ 2017
Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27027.1

with

error C2988: unrecognizable template declaration/definition
error C2059: syntax error: '('
error C2143: syntax error: missing ';' before '{'
error C2447: '{': missing function header (old-style formal list?)

Is the template function defined with incorrect syntax per spec (and GCC, Clang, some MSVC++ version(s) just somehow passes)?
Or is it something MSVC specific, MSVC flags specific, or yet recent MSVC specific?
Something else?
There is one similar issue, but my knowledge on templates does not allow to see, how it applies here.


Solution

  • Does your project include windows.h?

    Including windows.h also brings in preprocessor defines for OUT and IN which I think is causing this error.

    Changing the template typenames to OUTX and INX fixes the errors on my machine.

    I found a related SO question: IN and OUT macros in minwindef.h