Reputation: 171
I am having problems trying to specialize a template method of a class to accept a derived class. I've tried with pointers as well and end up with many more issues than this iteration.
#include <iostream>
using namespace std;
class Json {
public:
Json(){}
virtual ~Json(){}
template <class T>
bool Get(std::string key, T& value);
};
template <class T>
bool Json::Get(std::string key, T& value){
std::cout << "Call default GET" << std::endl;
}
template <>
bool Json::Get(std::string key, Json& value){
std::cout << "Call JSON GET" << std::endl;
}
class JsonError : public Json {
public:
JsonError(){}
~JsonError(){}
};
int main()
{
// OK
int int_value = 0;
Json json;
json.Get("int", int_value);
// OK
Json json_value;
json.Get("json", json_value);
// NOT OK
JsonError json_error_value;
json.Get("error", json_error_value);
return 0;
}
This should print out
Call default GET
Call JSON GET
Call JSON GET
Upvotes: 2
Views: 181
Reputation: 12928
That's not how templates work. Template deduction is always on the exact type, in this case JsonError
, so the specialization for Json&
is not matched.
If you still want to make it work, you can overload the template function with a member function taking Json&
. The template function will still be a better match for a derived type, so we also need to disable the template method for any type deriving from Json
.
#include <iostream>
class Json {
public:
Json(){}
virtual ~Json(){}
template <class T, std::enable_if_t<!std::is_base_of_v<Json, T>, int> = 0>
bool Get(std::string key, T& value);
bool Get(std::string key, Json& value);
};
template <class T, std::enable_if_t<!std::is_base_of_v<Json, T>, int> = 0>
bool Json::Get(std::string key, T& value){
std::cout << "Call default GET" << std::endl;
return true;
}
bool Json::Get(std::string key, Json& value){
std::cout << "Call JSON GET" << std::endl;
return true;
}
class JsonError : public Json {
public:
JsonError(){}
~JsonError(){}
};
int main()
{
// OK
int int_value = 0;
Json json;
json.Get("int", int_value);
// OK
Json json_value;
json.Get("json", json_value);
// NOW IT'S OK
JsonError json_error_value;
json.Get("error", json_error_value);
return 0;
}
Upvotes: 3