有选择地覆盖模板化类的功能

时间:2013-12-20 06:51:10

标签: c++ templates template-specialization

有一个模板类,如下所示

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;有不同的实现,我如何声明这样的模板类?

尝试过类似下面的内容,dint编译......

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;

};

2 个答案:

答案 0 :(得分:1)

在这种情况下,您不需要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

答案 1 :(得分:1)

为我上面的海报添加更多内容:

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

换句话说,如果你对整个数据库类进行部分特化的概念是正确的,如果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的函数和那些不需要的函数放在抽象的DB中。