I would like to put the implementation of the specializations of a templated function to a separate source file, but if I try to call it (in MyAction), I get this error:
Explicit specialization has already been instantiated
I have no idea, why I get this error. Example code:
main.cpp
#include <iostream>
#include <string>
#include "MyClass.h"
int main()
{
std::cout << "Hello, " << XX::MyClass().MyMethod<1>() << std::endl;
std::cin.get();
}
MyClass.h
#pragma once
#include <string>
namespace XX {
struct MyClass {
std::string MyAction() {
return MyMethod<0>() + MyMethod<1>();
}
template<int>
std::string MyMethod();
};
template<>
std::string MyClass::MyMethod<0>();
template<>
std::string MyClass::MyMethod<1>();
}
MyClass.cpp
#include "MyClass.h"
namespace XX {
template<>
std::string MyClass::MyMethod<0>() {
return "FOO";
}
template<>
std::string MyClass::MyMethod<1>() {
return "BAR";
}
}
Is there a template instantiation rule, which I am not aware of?
Ok looks like problem is an order.
When you are defining MyAction
compiler tries instantiate template, but he doesn't know about specialization.
When you declare MyAction
and define it in cpp after template specialization it will work.
// header part
#include <string>
namespace XX {
struct MyClass {
template<int>
std::string MyMethod();
std::string MyAction();
};
}
// cpp part
namespace XX {
template<>
std::string MyClass::MyMethod<0>() {
return "a";
}
template<>
std::string MyClass::MyMethod<1>() {
return "b";
}
std::string MyClass::MyAction() {
return MyMethod<0>() + MyMethod<1>();
}
}
See here: https://godbolt.org/z/aGSB21
Note if you move MyClass::MyAction()
above MyClass::MyMethod<1>()
error will come back.
Here is version where specialization is can be declared in header file: https://godbolt.org/z/kHjlne
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With