简体   繁体   English

如何在C ++中设计库包装器?

[英]How to design a library wrapper in C++?

I would like to design a wrapper in C++ with a simple syntax: 我想用简单的语法在C ++中设计一个包装器:

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: 这是我包装STL向量的代码:

#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. STL包装器是一种称为stl的结构。 This structure is actually a subclass of Wrapper class. 该结构实际​​上是Wrapper类的子类。 I have specialized stl structure for STL's vectors. 我对STL的向量有专门的stl结构。 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. 我希望能够从对(Vector,stl)中推断出,它对应于std :: vector的stl专业化。 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. 可以使用一些typedef或模板别名来执行此操作,但是我找不到它。 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. 等同于std :: vector,但从包装器中推导出来。 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! 谢谢!

This is fairly easy to do using C++11 syntax, or higher. 使用C ++ 11或更高版本的语法非常容易做到。

Here's an example of implementing a Vector wrapper, that will result in the syntax that you're looking for. 这是实现Vector包装器的示例,这将导致您要查找的语法。 Use a similar approach to implement Matrix , etc. 使用类似的方法来实现Matrix等。

The approach combines template specialization, with template using , selecting the correct specialization that declares a member type that's the actual type being declared: 该方法将模板专业化与template using结合起来,选择正确的专业化来声明成员类型,该成员类型是要声明的实际类型:

#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... 使用可变参数模板可以做进一步的工作,即一些额外的调整也可能导致一些额外的变化,例如将自定义分配器类型转发到std::vector等。

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

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