2015-03-08 6 views
1

Я хотел бы создать оболочку в C++ с простым синтаксисом:Как создать библиотечную оболочку на 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 

Однако мне не удается получить этот синтаксис, особенно для двух последних примеров. Вот мой код для случая оборачивать СТЛ векторов:

#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. У меня есть специализированная структура stl для векторов STL. Я могу сделать некоторые другие спецификации для некоторых контейнеров (списки, карты, ...). Таким образом, при объявлении

Vector<double,stl> vec 

Я хотел бы быть в состоянии вывести из пары (Вектор, СТЛ), что соответствует специализации СТЛ для станд :: вектор. Однако мне это не удается. Каждый раз, когда я что-то пробовал, я получаю бесконечную рекурсию над параметрами шаблона.

Может быть хороший способ сделать это с помощью некоторого typedef или псевдонима шаблона, но я не могу его найти. Это может быть примерно так:

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

где ???? было бы эквивалентно std :: vector, но выведено из Wrapper. Но я не знаю, возможно ли это.

Мой дизайн также может быть наивным. Я был бы очень признателен за любое предложение по его улучшению. Меня интересует только синтаксис кода.

Спасибо!

+0

Зачем вам это нужно? Классы кажутся довольно несвязанными и просто имеют похожие имена *. –

+0

Не могли бы вы подробнее объяснить, что вы имеете в виду? Я хотел бы обернуть внешние библиотеки, но без виртуальных функций (для поддержания производительности обернутых библиотек). – Aleph

+0

Я не вижу, что 'std :: vector ' и 'Eigen :: VectorXd ' имеют общее сходство, чем аналогичное имя, и очень широкое обобщение «содержит элементы». –

ответ

2

Это довольно легко сделать, используя синтаксис C++ 11 или выше.

Вот пример реализации обертки Vector, которая приведет к синтаксису, который вы ищете. Используйте аналогичный подход к реализации Matrix и т.д.

подход сочетает в себе шаблон специализации, с 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; 

С выше бытия определены:

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

Использование VARIADIC шаблонов позволяет некоторым дальнейшей работы, а именно несколько дополнительных настроек может также привести некоторые дополнительные, как пересылка пользовательских типов Allocator до std::vector и т. д.

+0

Большое спасибо за помощь. Не только ваше решение соответствует моим синтаксическим потребностям, но также приводит к очень простому и понятному коду. – Aleph