Enum with constexpr std::string_view vs instantiated enum with std::string

房东的猫 提交于 2019-12-13 00:49:46

问题


I would like to have structs holding enums for iteration, together with std::string holding their names for creating menu entries. I was using something like this:

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;
}

As I understand, this is preferred to having global variables. It works, but needs instantiation before usage. Now, I found out about this method, which needs --std=C++17 to compile:

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;
}

But how will this behave, in terms of memory usage, compared to my previous way of doing this? Or is there a wrong way in how I do it? What would be a better way?


回答1:


You don't need that enum when using std::array. You can do this:

struct S
{
    static constexpr std::array<std::string_view, 2> names { "one", "two" };
};

int main()
{
    for(auto name: S::names)
        std::cout << name << '\n';
}

Or this:

int main()
{
    for(auto n = std::begin(S::names); n != std::end(S::names); ++n)
        std::cout << *n << '\n';
}

This is very different from your first example though because now you only have one array for every sruct S. Before, every struct has its own copy of the array.

So do what suits your need. One array per object? Or one array for all your objects?




回答2:


It's not completely clear what you ask, but except from a few small errors in your example it's fine.

If we change the example a bit to not use iostream (because it's confusing with that much code in the assembly listing). An example, instead summing the size of the names:

#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;
}

It compiles to a few assembly instructions representing "return 6". But, as Galik points out, no need for the enum trick.

https://godbolt.org/g/ot2kpt

You can also pick a range to loop over, like this:

for(auto n = std::begin(S::names)+1; n != std::end(S::names); ++n)


来源:https://stackoverflow.com/questions/49598101/enum-with-constexpr-stdstring-view-vs-instantiated-enum-with-stdstring

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!