【发布时间】:2019-10-22 04:15:53
【问题描述】:
我有一个必须分配一次的字符串数组,并且它们的底层 c_str 必须在整个程序期间保持有效。
有一些 API 提供有关某些任意数据类型的信息。可能看起来像这样:
// Defined outside my code
#define NUMBER_OF_TYPES 23
const char* getTypeSuffix(int index);
getTypeSuffix 不是 constexpr,因此它必须至少部分在运行时工作。
我必须提供的界面:
// Returned pointer must statically allocated (not on stack, not malloc)
const char* getReadableTypeName(int type);
现在我的数组应该有以下类型:
std::string typeNames[NUMBER_OF_TYPES];
出于我的目的,它将在包装类中初始化,就在构造函数中:
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];
};
然后以单例方式使用,例如:
const char* getReadableTypeName(int type)
{
static MyNames names;
return names[type];
}
现在我要改进的是我可以看到构造函数中的for循环可以这样替换:
MyNames() : _names{std::string("Type ") + getTypeSuffix(0), std::string("Type ") + getTypeSuffix(1), ... , std::string("Type ") + getTypeSuffix(NUMBER_OF_TYPES-1)}
{}
显然是伪代码,但你明白了——数组可以直接初始化,构造函数没有主体,这很整洁。这也意味着数组成员_names可以是const,进一步强制了这个助手类的正确使用。
我很确定在编译时用表达式填充数组还有很多其他用途,而不是循环。我什至怀疑这是在03 期间无论如何都会发生的事情。
有没有办法编写具有灵活长度并由表达式定义的 C++11 样式数组初始化列表?另一个简单的例子是:
constexpr int numberCount = 10;
std::string numbers[] = {std::to_string(1), std::to_string(2), ... , std::to_string(numberCount)};
同样,一个表达式而不是一个循环。
我问这个问题不是因为我试图大幅提高性能,而是因为我想了解 C++14 及更高版本的新的、简洁的特性。
【问题讨论】:
-
老实说,我没有看到您的问题,该数组是
MyNames类的实现细节。唯一的公共访问器是提供恒定输出的操作员。 (您仍然可以将方法设为 const)您想要什么额外的优势? -
为什么不使用
std::array而不是C 风格的数组?