我希望struct
持有enum
进行迭代,同时std::string
保留其名称以创建菜单条目。我正在使用这样的东西:
struct S
{
enum E { ONE, TWO, ALL };
std::array<std::string, ALL> names { "one", "two" };
};
int main()
{
S s;
for(int i=s.ONE; i<s.ALL; ++i) // or S::...
std::cout << s.names[i] << '\n';
return 0;
}
据我所知,这是全局变量的首选。它可以工作,但需要在使用前进行实例化。现在,我发现了这个方法,需要--std=C++17
来编译:
struct S
{
enum E { ONE, TWO, ALL };
static constexpr std::array<std::string_view, ALL> names { "one, "two" };
};
int main()
{
for(int i=S::ONE; i<S::ALL, ++i)
std::cout << S::names[i] << '\n';
return 0;
}
但就内存使用而言,与我之前的做法相比,这将如何表现呢?或者我是怎么做错的?什么是更好的方式?
答案 0 :(得分:2)
你问的问题并不完全清楚,但除了你的例子中的一些小错误外,没关系。
如果我们稍微更改示例以不使用iostream(因为它与汇编列表中的那么多代码混淆)。一个例子,而不是总结名称的大小:
#include <string_view>
#include <array>
struct S
{
enum E { ONE, TWO, ALL };
static constexpr std::array<std::string_view, ALL> names { "one", "two" };
};
int main()
{
int l=0;
for(int i=S::ONE; i<S::ALL; ++i){
l+= S::names[i].size() ;
}
return l;
}
它编译成一些表示“返回6”的汇编指令。但是,正如加利克指出的那样,不需要枚举技巧。
您还可以选择要循环的范围,如下所示:
for(auto n = std::begin(S::names)+1; n != std::end(S::names); ++n)
答案 1 :(得分:2)
使用enum
时,您不需要std::array
。你可以这样做:
struct S
{
static constexpr std::array<std::string_view, 2> names { "one", "two" };
};
int main()
{
for(auto name: S::names)
std::cout << name << '\n';
}
或者这个:
int main()
{
for(auto n = std::begin(S::names); n != std::end(S::names); ++n)
std::cout << *n << '\n';
}
这与您的第一个示例非常不同,但是因为现在您只有 一个 sruct S
的一个数组。之前,每个结构都有自己的数组副本。
那么做什么适合你的需要。每个对象一个数组?或者所有你的对象的一个数组?