sbi*_*sbi 10 c++ templates template-meta-programming
我有一堆有名字的类型.(它们有更多功能,但为了讨论起见,只有名称是相关的.)这些类型及其名称是在编译时使用宏设置的:
#define DEFINE_FOO(Foo_) \
struct Foo_ : public foo_base<Foo_> { \
static char const* name() {return #Foo_;} \
}
Run Code Online (Sandbox Code Playgroud)
然后将这些类型组合在编译时列表(经典的简单递归编译时列表)中,我需要通过连接其对象的名称来创建列表的名称:
template<class Foo, class Tail = nil>
struct foo_list {
static std::string name_list() {return Foo::name() + "-" + Tail::name();}
};
template<class Foo>
struct foo_list<Foo,nil> {
static std::string name_list() {return Foo::name();}
};
Run Code Online (Sandbox Code Playgroud)
代码在这里归结为它可能包含错误的程度,但实际上这很好用.
除了它在运行时创建然后复制相当长的字符串,这些字符串表示在编译时实际上是众所周知的类型.由于这是一个在嵌入式设备上运行的性能相当敏感的代码,我想改变这一点
我怎样才能做到这一点?
(如果这扩大了可用于此的脏技巧:foo只能通过代码创建和读取对象的foo_list名称,并且只有名称字符串应该是人类可读的.)
您可能想看看 boost 的mpl::string. 我的咖啡喝完后可以遵循的例子......
编辑:所以咖啡已经开始了......:)
#include <iostream>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/string.hpp>
#include <boost/mpl/vector.hpp>
namespace mpl = boost::mpl;
struct foo
{
typedef mpl::string<'foo'> name;
};
struct bar
{
typedef mpl::string<'bar'> name;
};
struct gah
{
typedef mpl::string<'gah'> name;
};
namespace aux
{
template <typename string_type, typename It, typename End>
struct name_concat
{
typedef typename mpl::insert_range<string_type, typename mpl::end<string_type>::type, typename mpl::deref<It>::type::name>::type base;
typedef typename aux::name_concat<base, typename mpl::next<It>::type, End>::name name;
};
template <typename string_type, typename End>
struct name_concat<string_type, End, End>
{
typedef string_type name;
};
}
template <typename ...Types>
struct type_list
{
typedef mpl::string<> base;
typedef mpl::vector<Types...> type_seq;
typedef typename aux::name_concat<base, typename mpl::begin<type_seq>::type, typename mpl::end<type_seq>::type>::name name;
};
int main(void)
{
typedef typename type_list<foo, bar, gah>::name tlist_name;
std::cout << mpl::c_str<tlist_name>::value << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我相信您有足够的能力根据您的情况调整上述内容。注意:您必须忽略多字符常量警告...
还有一些注意事项:传递给的多字符常量mpl::string不能超过 4 个字符,因此,必须将其分块(或由单个字符构造),因此可以是长字符串,mpl::string<'this', ' is ', 'a lo', 'ng s', 'trin', 'g'>如果无法做到这一点,那么上面的方法将不起作用..:/
| 归档时间: |
|
| 查看次数: |
1840 次 |
| 最近记录: |