我有一堆有名字的类型。 (它们有更多的特性,但为了讨论起见,只有名称是相关的。)这些类型和它们的名称是在编译时使用宏设置的:
#define DEFINE_FOO(Foo_) \
struct Foo_ : public foo_base<Foo_> { \
static char const* name() {return #Foo_;} \
}
然后将这些类型组合在编译时列表(经典的简单递归编译时列表)中,我需要通过连接其对象的名称来创建列表的名称:
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();}
};
此处的代码被归结为可能包含错误的程度,但在实践中效果很好。
除了它在运行时创建并复制相当长的字符串外,这些字符串表示在编译时实际上众所周知的类型。由于这是一段在嵌入式设备上运行的对性能相当敏感的代码,我想对此进行更改,以便
- 列表的字符串最好在编译时创建,或者,如果没有办法做到这一点,则在运行时创建一次,并且
- 我只需要复制指向 C 字符串的指针,因为根据 #1,字符串在内存中是固定的。
- 它使用我们现在坚持使用的 C++03 进行编译。
我该怎么做?
(如果这扩大了可用于此的肮脏技巧的武器库: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;
}
我相信您有足够的能力根据自己的情况调整上述内容。注意:您将不得不忽略多字符常量警告...
更多注意事项:传递给 mpl::string
的多字符常量不能超过 4 个字符,因此,必须将其分块(或由单个字符构成),因此长字符串可能是 mpl::string<'this', ' is ', 'a lo', 'ng s', 'trin', 'g'>
如果无法做到这一点,那么上面的方法将不起作用..:/
关于c++ - 如何在编译时从类型创建静态字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19535290/