繁体   English   中英

c ++模板特化与派生类

[英]c++ Template specialization with derived class

我在尝试专门化类的模板方法以接受派生类时遇到问题。 我也尝试过使用指针,但最终遇到了比这次迭代更多的问题。

#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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM