Tom*_*ica 2 c++ arrays c++11 c++14
我有一个字符串数组,必须分配一次,并且它们的底层c_str必须在程序的整个持续时间内保持有效。
有一些API提供有关某些任意数据类型的信息。可能看起来像这样:
// Defined outside my code
#define NUMBER_OF_TYPES 23
const char* getTypeSuffix(int index);
Run Code Online (Sandbox Code Playgroud)
该getTypeSuffix不是constexpr,那么这必须工作至少部分地在运行时。
我必须提供的接口:
// Returned pointer must statically allocated (not on stack, not malloc)
const char* getReadableTypeName(int type);
Run Code Online (Sandbox Code Playgroud)
现在我的数组应该具有以下类型:
std::string typeNames[NUMBER_OF_TYPES];
Run Code Online (Sandbox Code Playgroud)
就我的目的而言,它将在包装器类中初始化,就在构造函数中:
class MyNames
{
MyNames()
{
for (int i = 0; i < NUMBER_OF_TYPES; ++i)
{
names[i] = std::string("Type ") + getTypeSuffix(i);
}
}
const char* operator[](int type) { return _names[(int)type].c_str(); }
private:
std::string _names[NUMBER_OF_TYPES];
};
Run Code Online (Sandbox Code Playgroud)
然后以单例形式使用这种方式,例如:
const char* getReadableTypeName(int type)
{
static MyNames names;
return names[type];
}
Run Code Online (Sandbox Code Playgroud)
现在,我要改进的是,我可以看到构造函数中的for循环可以这样替换:
MyNames() : _names{std::string("Type ") + getTypeSuffix(0), std::string("Type ") + getTypeSuffix(1), ... , std::string("Type ") + getTypeSuffix(NUMBER_OF_TYPES-1)}
{}
Run Code Online (Sandbox Code Playgroud)
显然是伪代码,但您明白了这一点-可以直接初始化数组,而使构造函数没有主体,这很整洁。这也意味着该数组成员_names可以是const,进一步加强了此帮助器类的正确用法。
我很确定在编译时将有许多其他用途来通过表达式填充数组,而不是具有循环。我什至怀疑这是在期间发生的事情03。
有没有一种方法可以编写长度可变且由表达式定义的C ++ 11样式数组初始化程序列表?另一个简单的示例是:
constexpr int numberCount = 10;
std::string numbers[] = {std::to_string(1), std::to_string(2), ... , std::to_string(numberCount)};
Run Code Online (Sandbox Code Playgroud)
同样,用表达式代替循环。
我之所以问这个问题不是因为我试图大幅提高性能,而是因为我想了解C ++ 14和更高版本的新特性。
而不是使用C-array std::array,则可以编写函数以返回该函数,std::array然后您的成员可以是const:
std::array<std::string, NUMBER_OF_TYPES> build_names()
{
std::array<std::string, NUMBER_OF_TYPES> names;
for (int i = 0; i < NUMBER_OF_TYPES; ++i)
{
names[i] = std::string("Type ") + getTypeSuffix(i);
}
return names;
}
class MyNames
{
MyNames() : _names(build_names()) {}
const char* operator[](int type) const { return _names[(int)type].c_str(); }
private:
const std::array<std::string, NUMBER_OF_TYPES> _names;
};
Run Code Online (Sandbox Code Playgroud)
现在,有了std::array,您可以使用可变参数模板而不是循环,例如(std::index_sequence东西是C ++ 14,但可以在C ++ 11中实现):
template <std::size_t ... Is>
std::array<std::string, sizeof...(Is)> build_names(std::index_sequence<Is...>)
{
return {{ std::string("Type ") + getTypeSuffix(i) }};
}
Run Code Online (Sandbox Code Playgroud)
然后调用它:
MyNames() : _names(build_names(std::make_index_sequence<NUMBER_OF_TYPES>())) {}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
114 次 |
| 最近记录: |