C++ 动态编译时混合
我试图找到一种在编译时定义动态混合的方法。我目前有一个非常粗糙的解决方案,它只能部分实现我想要的,但我不确定如何改进它 我知道使用Type的更多的C++类解决方案,但是它们需要静态地定义所有的类型,我试图避免。p> <>这只是一个思想练习,学习C++更好,我确信我当前的实现不是很好的C++。欢迎提出任何改进建议或尝试不同想法 我目前实施的主要问题是:C++ 动态编译时混合,c++,c++11,mixins,C++,C++11,Mixins,我试图找到一种在编译时定义动态混合的方法。我目前有一个非常粗糙的解决方案,它只能部分实现我想要的,但我不确定如何改进它 我知道使用Type的更多的C++类解决方案,但是它们需要静态地定义所有的类型,我试图避免。p> 这只是一个思想练习,学习C++更好,我确信我当前的实现不是很好的C++。欢迎提出任何改进建议或尝试不同想法 我目前实施的主要问题是: 每个mixin类只知道它自己以及层次结构中比它自己低的类。我希望每个mixin类能够返回一个具有不同底层类型的新mixin。在下面的示例代码中,我希
- 每个mixin类只知道它自己以及层次结构中比它自己低的类。我希望每个mixin类能够返回一个具有不同底层类型的新mixin。在下面的示例代码中,我希望
能够有一个返回PrintOnce
对象的方法printTworth
- 这个想法的任何使用都需要有一个标题包含顺序。开始时的所有锅炉板代码都需要在一个标题中,然后需要定义所有的mixin类,最后可以定义
函数。当前,在make_mixed
函数之后定义的任何mixin都将被忽略李>make\u mixed
- 宏和实现的一般缺陷
#include <string>
#include <vector>
#include <iostream>
using namespace std;
template<class Underlying>
struct Printer
{
Printer(const Underlying &val) : val_(val) {}
Underlying get_val() { return val_; }
private:
Underlying val_;
};
#define CURRENT_NUMBER_MIXED_IN_CLASSES() \
MixinCount<0, __LINE__>::value
#define INCREMENT_MIXIN_CLASS_COUNTER() \
template<int id> \
struct MixinClassCounter< CURRENT_NUMBER_MIXED_IN_CLASSES(), id> \
{ \
static const bool is_defined = true; \
}
template< bool b, typename i, typename j >
struct select_value;
template<class i, class j>
struct select_value<true, i, j>
{
static const int value = i::value;
};
template<class i, class j>
struct select_value<false, i, j>
{
static const int value = j::value;
};
template<int i>
struct IntToVal
{
static const int value = i;
};
namespace
{
template<int count, int id>
struct MixinClassCounter
{
static const bool is_defined = false;
};
template<int count, int id>
struct MixinCount
{
static const int value = select_value<MixinClassCounter<count, id>::is_defined,
MixinCount<count + 1, id>,
IntToVal<count> >::value;
};
template<class Underlying, int i>
struct MixinBuilder {};
template<class Underlying>
struct MixinBuilder<Underlying, 0>
{
typedef Printer<Underlying> type;
};
INCREMENT_MIXIN_CLASS_COUNTER();
}
#define DECLARE_MIXIN_BEGIN(name) \
template<class Base> \
struct name : Base \
{ \
template<class Underlying> \
name(const Underlying &val) : Base(val) {}
#define DECLARE_MIXIN_END(name) \
}; \
namespace \
{ \
template<class Underlying> \
struct MixinBuilder<Underlying, CURRENT_NUMBER_MIXED_IN_CLASSES()> \
{ \
typedef name< typename MixinBuilder<Underlying, CURRENT_NUMBER_MIXED_IN_CLASSES() - 1>::type > type; \
}; \
INCREMENT_MIXIN_CLASS_COUNTER(); \
} \
DECLARE_MIXIN_BEGIN(PrintOnce)
void print_once()
{
cout << Base::get_val() << endl;
}
DECLARE_MIXIN_END(PrintOnce)
DECLARE_MIXIN_BEGIN(PrintTwice)
void print_twice()
{
cout << Base::get_val() << endl;
cout << Base::get_val() << endl;
}
DECLARE_MIXIN_END(PrintTwice)
template<class T>
typename MixinBuilder<T, CURRENT_NUMBER_MIXED_IN_CLASSES() - 1>::type make_mixed(const T &val)
{
return typename MixinBuilder<T, CURRENT_NUMBER_MIXED_IN_CLASSES() - 1>::type(val);
}
int main()
{
string test("this is a test");
auto printable_string = make_mixed(test);
printable_string.print_once();
printable_string.print_twice();
}
#包括
#包括
#包括
使用名称空间std;
模板
结构打印机
{
打印机(常量和val):val_(val){}
底层get_val(){return val;}
私人:
潜在价值;
};
#在\u类()中定义当前\u编号\u混合\u\
MixinCount::value
#定义增量\u混合\u类\u计数器()\
模板\
结构MixinClassCounter\
{ \
静态常数布尔值定义为真\
}
模板
结构选择_值;
模板
结构选择值
{
静态常量int value=i::value;
};
模板
结构选择值
{
静态常量int value=j::value;
};
模板
结构IntToVal
{
静态常数int值=i;
};
名称空间
{
模板
结构MixinClassCounter
{
静态常量布尔值为_defined=false;
};
模板
结构混合计数
{
静态常量int值=选择值::值;
};
模板
结构MixinBuilder{};
模板
结构混合生成器
{
打印机类型;
};
增量混合类计数器();
}
#定义DECLARE\u MIXIN\u BEGIN(名称)\
模板\
结构名称:Base\
{ \
模板\
名称(const-underlined&val):基(val){}
#定义DECLARE\u MIXIN\u END(名称)\
}; \
名称空间\
{ \
模板\
结构混合生成器\
{ \
typedef nametype\
}; \
增量混合类计数器()\
} \
声明混合开始(打印一次)
作废打印一次()
{
cout这里有一个没有宏的更干净的解决方案:
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
template <typename T>
struct RefWrapper
{
T *self;
RefWrapper () : self (nullptr) {abort ();} // should never be called
RefWrapper (T &self) : self (&self) {}
};
template <typename T>
struct PrintOnce : virtual RefWrapper<T>
{
PrintOnce () {} // workaround gcc 4.6 bug
void print_once () {cout << *RefWrapper<T>::self << endl;}
};
template <typename T>
struct PrintTwice : virtual RefWrapper<T>
{
PrintTwice () {} // workaround gcc 4.6 bug
void print_twice ()
{
cout << *RefWrapper<T>::self << endl;
cout << *RefWrapper<T>::self << endl;
}
};
template <typename T, typename... Args>
struct Mixed : Args...
{
Mixed (T &self) :
RefWrapper<T> (self),
Args ()... {}
Mixed (const Mixed ©) :
RefWrapper<T> (*copy.self),
Args ()... {}
};
template <template <typename U> class Mixin, typename T>
Mixed<T, Mixin<T> > add_mixin (T &original)
{
return Mixed<T, Mixin<T> > (original);
}
template <template <typename U> class Mixin, typename T,
typename... OtherMixins>
Mixed<T, OtherMixins..., Mixin<T> >
add_mixin (Mixed<T, OtherMixins...> &original)
{
return Mixed<T, OtherMixins..., Mixin<T> > (*original.self);
}
int main ()
{
string foo = "test";
auto p1 = add_mixin<PrintOnce> (foo);
p1.print_once ();
auto p2 = add_mixin<PrintTwice> (p1);
p2.print_once ();
p2.print_twice ();
}
#包括
#包括
使用std::cout;
使用std::endl;
使用std::string;
模板
结构参照包装器
{
T*self;
RefWrapper():永远不应调用self(nullptr){abort();}//
RefWrapper(T&self):self(&self){}
};
模板
结构PrintOnce:虚拟RefWrapper
{
PrintOnce(){}//解决GCC4.6错误的方法
void print_once(){cout这不是一个解决方案,但是Boost预处理器库可能会帮助您实现您想要做的事情。