How to properly combine template Repository class and CRTP pattern to provide both type polymorphism and eliminate virtual call cost?

Viewed 186

This is a repository class, which has such interface. As you can see, the key type and value type are both template parameters. I add an extra Impl parameter, since i want to use the CRTP pattern to eliminate virtual call cost.

template <typename K, typename V, typename Impl>
class Repository{
public:
    V get(const K& key){
        return static_cast<Impl*>(this)->get(key);
    }
};

And the dummy implementation class goes here:

struct MockData{
    char data[16384];
};

class RepositoryImpl : public Repository<int, MockData, RepositoryImpl>{
public:
    MockData get(const int& key){
        std::cout << "haha";
        return MockData{};
    }
};

The caller has such signature:

template<typename Impl>
MockData doSomething(Repository<int, MockData, Impl>* obj){
    return obj->get(1);
}

And there might be more than one RepositoryImpl that has the same K V interface. For example, a SQLiteBasedRepo or a LMDBBasedRepo...


The above code can compile, but what i want to ask is, is it the proper way to combine template Repository class and CRTP pattern to provide both type polymorphism and eliminate virtual call cost? The current implementation mix the CRTP implementation detail(the Impl template parameter) and the functional parameter(K and V) together, which is a little bit strange to me.

0 Answers
Related