派生クラスを受け付けるようにクラスのテンプレートメソッドを特殊化しようとすると問題が発生します。私もポインタを試してみましたが、この反復よりも多くの問題が発生します。
#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;
}
これは印刷する必要があります
Call default GET
Call JSON GET
Call JSON GET
それはテンプレートが機能する方法ではありません。テンプレートの控除は常に正確なタイプ(この場合JsonError
)に基づいているため、の特殊化Json&
は一致しません。
それでも機能させたい場合は、メンバー関数がを使用してテンプレート関数をオーバーロードできますJson&
。テンプレート関数は引き続き派生型に適しています。そのため、から派生するすべての型のテンプレートメソッドを無効にする必要もあり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;
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加