有选择地覆盖模板化类的函数

Selectively override functions of templated class

本文关键字:函数 选择地 覆盖      更新时间:2023-10-16

有一个模板类,如下所示

template<typename K, typename V>
class Db {
public:
    Db(const string& dbname, int flags = O_RDWR|O_CREAT);
    ~Db();
    // return true on success, false on failure
    bool SimpleRetrieve(const K&, V&) const;
    bool Retrieve(const K&, V&) const;
};


而,想要对SimpleRetrieve(const K&, string &) const;有不同的实现,如何声明这样的模板类?

尝试了下面这样的东西,编译...

template<typename K, typename V>
class Db {
public:
    Db(const string& dbname, int flags = O_RDWR|O_CREAT);
    ~Db();
    // return true on success, false on failure
    bool SimpleRetrieve(const K&, V&) const;
    template<>
    bool SimpleRetrieve(const K&, string&) const;
    bool Retrieve(const K&, V&) const;
};

在这种情况下,您不需要template<>有 2 个重载。

但是如果你想要模板化类方法,afaik,你不能这样做,因为在非命名空间范围内不允许专用化。

所以,这应该可以正常工作:

template<typename K, typename V>
class Db {
    public:
        Db(const string& dbname, int flags = O_RDWR|O_CREAT);
        ~Db();
        // return true on success, false on failure
        bool SimpleRetrieve(const K&, V&) const;
        bool SimpleRetrieve(const K&, string&) const;
        bool Retrieve(const K&, V&) const;
};

但我不确定你的编译器将如何使用这种重载,你可能应该看看 std::enable_if。

为了补充我上面的海报所说的话:

模板类中不能具有部分专用的成员函数,除非整个类是部分专用的。

换句话说,如果你同意在 V 是一个字符串的情况下对整个数据库类进行部分特化的概念,你可以做类似的事情

template<typename K>
class DB<K, string>{
//rest of your stuff here
} 

编辑:

关于Joachim Pileborg,这里有一个替代方案,不需要你重新实现整个数据库类。我省略了一些细节,但这个想法应该很清楚:

template<typename K, typename V>
class AbstractDb {
public:    
    bool Retrieve(const K&, V&) const { std::cout << "Retrieve for K and V" << std::endl; return true; };
};

template<typename K, typename V>
class Db: public AbstractDb<K, V>{
public:
    bool SimpleRetrieve(const K&, const V&) const {std::cout << "Generic Db2 Simple Retrieve" << std::endl; return true;};
};
template<typename K>
class Db<K, std::string> : public AbstractDb<K, std::string>{
public:
    bool SimpleRetrieve(const K&, const std::string&) const {std::cout << "SPecialized Db2 Simple Retrieve" << std::endl; return true;};
};

int main()
{
    Db2<int, int> db;
    int a = 4, b = 5;  
    db.SimpleRetrieve(a,b);
    db.Retrieve(a,b);
    Db2<int, std::string> specdb;
    std::string str = "abcd";
    std::string str2 = "abcd2";
    specdb.SimpleRetrieve(a, str);
    specdb.Retrieve(a, str2);    
    return 0;
}

其输出为:

Generic Db2 Simple Retrieve
Retrieve for K and V
SPecialized Db2 Simple Retrieve
Retrieve for K and V

你会把需要专用于DB的函数和不需要的函数放在抽象数据库中。