How to design a library wrapper in C++?

左心房为你撑大大i 提交于 2019-12-24 12:40:28

问题


I would like to design a wrapper in C++ with a simple syntax:

Vector<double,stl> v; // aka std::vector<double>
Vector<double, eigen> w; // aka Eigen::VectorXd from Eigen library
Matrix<double, eigen> m; // aka Eigen::MatrixXd from Eigen library

However, I do not manage to get this syntax, especially for the two last examples. Here is my code for the case of wrapping of STL vectors:

#ifndef WRAPPER_HPP
#define WRAPPER_HPP

#include <cstdlib>
#include <vector>

//=============
// BASE WRAPPER
//=============

template<class ScalarType, template<class,class...> class WrappedType>
class Wrapper
{
protected:
  WrappedType<ScalarType> wrapped_;
};

//==============
// STL WRAPPER
//==============

template<class ScalarType, template<class,class...> class WrappedType>
struct stl;

template<class ScalarType>
struct stl<ScalarType,std::vector> : public Wrapper<ScalarType,std::vector>
{
public:
  size_t size()
  { return this->wrapped_.size(); }
};

//=======
// VECTOR
//=======
template<class ScalarType, template<class, template<class,class...> class> class Wrapper>
using Vector = Wrapper<ScalarType,std::vector>;
// **** Problem : I should not provide "std::vector" above ****

#endif

STL wrapper is a structure called stl. This structure is actually a subclass of Wrapper class. I have specialized stl structure for STL's vectors. I may do some other specalizations for some containers (lists, maps, ...). Thus, when declaring

Vector<double,stl> vec

I would like to be able to deduce from the pair (Vector, stl) that it corresponds to the specialization of stl for std::vector. However, I do not manage to do it. Each time I try something, I get an infinite recursion over template parameters.

There may be a good way to do this with some typedef or template alias but I cannot find it. It may be something like that:

template<class ScalarType, template<class, template<class,class...> class> class Wrapper>
using Vector = Wrapper<ScalarType,????>;

where ???? would be something equivalent to std::vector, but deduced from Wrapper. But I do not know if it is possible.

My design may also be naive. I would really appreciate any suggestion to improve it. I am only interested in the syntax of the code.

Thanks!


回答1:


This is fairly easy to do using C++11 syntax, or higher.

Here's an example of implementing a Vector wrapper, that will result in the syntax that you're looking for. Use a similar approach to implement Matrix, etc.

The approach combines template specialization, with template using, selecting the correct specialization that declares a member type that's the actual type being declared:

#include <vector>

class stl; // dummy class
class eigen; // dummy class

template<typename ...Args> class vector_impl;

template<>
class vector_impl<double, stl> {

public:
    typedef std::vector<double> impl_type;
};

template<>
class vector_impl<double, eigen> {

public:
    typedef Eigen::VectorXd impl_type;   // I presume...
};

// And the magical alias:

template<typename ...Args>
using Vector=typename vector_impl<Args...>::impl_type;

With the above being defined:

Vector<double, stl> a;    // This declares a std::vector<double>
Vector<double, eigen> b;  // This declares an `Eigen::VectorXd`

Using variadic templates allows for some further work, namely a few additional tweaks can also result in some extras, like forwarding custom allocator types to std::vector, etc...



来源:https://stackoverflow.com/questions/28929071/how-to-design-a-library-wrapper-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!