Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this code compile with g++ but not MSVC++?

I'm trying to compile some open-source code (https://github.com/BieremaBoyzProgramming/bbpPairings), which I can get to compile on linux using g++ (v6.3.0), but which fails to compile in Visual Studio (VS Community 2019/16.1.5), with the somewhat obscure (to me, but my C++ is admittedly weak) error: "error C2143: syntax error: missing ';' before '<'".

The offending code in the source is here, but a minimal example extracted from the code is:

#include <iostream>
#include <random>

class Configuration {};

class MatchesConfiguration {
public:
    template <class RandomEngine>
    MatchesConfiguration(
        Configuration&&,
        RandomEngine&);
};

template <class RandomEngine>
MatchesConfiguration::MatchesConfiguration(
    Configuration&& configuration,
    RandomEngine& randomEngine) {}

template
MatchesConfiguration::MatchesConfiguration<std::minstd_rand>( // <--- SYNTAX ERROR HERE
    Configuration&&,
    std::minstd_rand&);

int main()
{
    std::cout << "Hello World!\n"; 
}

I've had a look at the MSDN description of the error code, but my grasp of C++ and templates is too tenuous to figure out what's going wrong. The project README says that C++14 is expected (with some optional C++17 stuff for FS stuff which shouldn't matter here I think), but as far as I can make out from the feature compatibility chart all of C++14 should be supported by VS 2019.

like image 921
arnsholt Avatar asked Jul 04 '19 17:07

arnsholt


People also ask

What compiler does MSVC use?

Microsoft C++ Compiler (MSVC) This is the default compiler for most Visual Studio C++ projects and is recommended if you are targeting Windows.

How do I use GCC instead of G ++?

The different options of GCC command allow the user to stop the compilation process at different stages. g++ command is a GNU c++ compiler invocation command, which is used for preprocessing, compilation, assembly and linking of source code to generate an executable file.

Why G ++ is not recognized VS Code?

If you don't see the expected output or g++ or gdb is not a recognized command, make sure your PATH entry matches the Mingw-w64 binary location where the compilers are located. If the compilers do not exist at that PATH entry, make sure you followed the instructions on the MSYS2 website to install Mingw-w64.

Does MSVC compile C?

Microsoft C/C++ (MSVC) is a C and C++ compiler that, in its latest versions, conforms to some of the latest C language standards, including C11 and C17.


1 Answers

When you provide an explicit instantiation definition of a constructor (which does not really have a name according to the standard), you should do it by supplying the signature you'd like to instantiate, like so:

template
MatchesConfiguration::MatchesConfiguration(  // no <std::minstd_rand> here
    Configuration&&,
    std::minstd_rand&);

[temp.arg.explicit#2]

Template arguments shall not be specified when referring to a specialization of a constructor template


Trivia from an old note (from 2006):
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#581

"Can a templated constructor be explicitly instantiated or specialized?"

it is not possible to specify a constructor's template arguments in a constructor invocation (because the constructor has no name but is invoked by use of the constructor's class's name)

[...]

It was observed that explicitly specifying the template arguments in a constructor declaration is never actually necessary because the arguments are, by definition, all deducible and can thus be omitted.

Note that normal function templates can have non-deducible template parameters that must be supplied explicitly for an instantiation or specialization.

Thanks to Davis Herring and M.M for guidance

like image 175
Ted Lyngmo Avatar answered Oct 06 '22 08:10

Ted Lyngmo