Reputation: 3872
I am having issues in understanding and fixing a compiler error that I see with MinGW (UCRT64) C++20, but that I don't see when I build the code with MSBuild C++11.
header.h: (Only relevant code)
#pragma once
// Has other necessary inclusions
#include <string>
#include <map>
struct Foo {
// Assumptions:
// Has some members
// Has variants of constructors
};
using Fooes = std::multimap<size_t, Foo>;
template <typename S>
std::string retrieveData(S& params, const std::string& tag, const std::string& initval);
extern template bool retrieveData<const Fooes>(const Fooes& params, const std::string& tag, bool initval);
// There are similar such retrieveData `extern template`s which deals with different data types for args and returning
// I have commented them out with the thought that I'll fix one and deal with the remaining later
Source.cpp: (Only relevant code)
// Safe to assume that:
// Has other necessary inclusions
#include <header.h>
Fooes::const_iterator retrieveEntry(const Fooes& params, const std::string& tag) {
// Impl that is already functional, has no warnings
}
template<>
std::string retrieveData<const TaxParameters>(const TaxParameters& params, const std::string& tag, const std::string& initval) {
const auto matchedEntry = retrieveEntry(params, tag);
if (matchedEntry == params.cend()) {
return initval;
}
return matchedEntry->second.value;
}
// There are similar such retrieveData impl which deals with different data types for args and returning
// I have commented them out with the thought that I'll fix one and deal with the remaining later
Compilation Error that I get:
error: specialization of 'std::string retrieveData(S&, const std::string&, const std::string&) [with S = const std::multimap<long long unsigned int, Foo>; std::string = std::__cxx11::basic_string<char>]' after instantiation
std::string retrieveData<const Fooes>(const Fooes& params, const std::string& tag, const std::string& initval)
I looked at the CPP reference to understand the Explicit instantiations as I have never worked with those. It talks about usage of extern template
in following way:
extern template return-type name < argument-list > ( parameter-list ) ; (3) (since C++11)
extern template return-type name ( parameter-list ) ; (4) (since C++11)
And,
An explicit instantiation definition forces instantiation of the function or member function they refer to. It may appear in the program anywhere after the template definition, and for a given argument-list, is only allowed to appear once in the program, no diagnostic required.
An explicit instantiation declaration (an extern template) prevents implicit instantiations: the code that would otherwise cause an implicit instantiation has to use the explicit instantiation definition provided somewhere else in the program.
I am so confused to figure out in my code which one is explicit instantiation definition and which one is explicit instantiation declaration, And do I refer to the implementation of the function in source.cpp as Specialization as the compilation error says.
What is the correct way to fix this error?
Upvotes: 1
Views: 90
Reputation: 21
in header.h, the return type of specialization should be
extern template std::string
retrieveData<const Fooes>(const Fooes& params, const std::string& tag, bool initval);
Upvotes: 2