c++templatescl

Unable to Compile Any Template Code with cl.exe


I'm attempting to compile some C++ code into a DLL file using cl.exe on Windows 10. It appears that I am unable to compile any code using templates at all because of error C2187, using the Visual Studio 2022 Developer Command Prompt.


As a simple example, attempting to compile the following test.cpp file with just one function TestFx that directly returns the templated argument it recieves:

template <typename T>
extern "C" __declspec(dllexport) T __stdcall TestFx(T arg) {return arg;}

With the command cl.exe /std:c++20 test.cpp, results in:

C2187: syntax error: 'string' was unexpected here

enter image description here

I'm not quite sure what this error is trying to tell me. There appear to be no Visual Studio documentations on error C2187, and it does not appear to have a page on the official Microsoft compiler error list.

At first I thought that this error may be caused by string being undefined when the compiler creates all the template versions of TestFx, but adding include <iostream> or include <string> and using namespace std; yields the same error.

It's even more confusing to me, because attempting to compile something like:

#include <iostream>

template <typename T>
T TestFx(T arg) 
{ 
    return arg; 
}

int main() 
{
    std::cout << TestFx(1) << "\n";
    std::cout << TestFx(5.5) << "\n";
    std::cout << TestFx("test") << "\n";

    return 0;
}

Works without issues in regular Visual Studio when compiling to an EXE:

1
5.5
test

Am I missing some compiler or linker flags here in order to enable templates to be compiled to a DLL using cl.exe?

Thanks for reading my post, any guidance is appreciated.


Solution

  • You seemed to ignore the first error and post the second one. If you started fixing your code from the first error C2988: unrecognizable template declaration/definition, you would find out that templates may not be declared with extern "C". This is compiled well

    template <typename T>
    __declspec(dllexport) T __stdcall TestFx(T arg) {
      return arg;
    }
    

    BTW I don't see any advantages of using __declspec(dllexport) and __stdcall with a template that is implemented in a header file.