-1

I am trying to create a Look-Up Table for easy creation of objects with different values. For this I need a static std::array in my class filled with the data. It currently looks like this:

#include <iostream>

#include <array>
#include <string>

struct MyStruct{
    std::string s;
    int a;
    int b;
};

class Arr{
public:
    static constexpr std::array<MyStruct, 3> strArray{{{"a", 1,2}, {"b", 2,3}, {"c", 3,4}}};
};

constexpr std::array<MyStruct, 3> Arr::strArray;

int main()
{    
    for(auto i : Arr::a){
        std::cout << i << std::endl;
    }

    std::cout << "With a struct:\n";
    for(auto i : Arr::strArray){
        std::cout << i.a << ", " << i.b << std::endl;
    }



    return 0;
}

It works fine, if I remove the std::string, but with the std::string I get the compile error

../staticArray/main.cpp:15:46: error: constexpr variable cannot have non-literal type 'const std::array<MyStruct, 3>'
    static constexpr std::array<MyStruct, 3> strArray{{{"a", 1,2}, {"b", 2,3}, {"c", 3,4}}};
                                             ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/array:137:16: note: 'array<MyStruct, 3>' is not literal because it has data member '__elems_' of non-literal type 'value_type [3]'
    value_type __elems_[_Size > 0 ? _Size : 1];
               ^
../staticArray/main.cpp:19:40: error: constexpr variable cannot have non-literal type 'const std::array<MyStruct, 3>'
constexpr std::array<MyStruct, 3> Arr::strArray;
                                       ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/array:137:16: note: 'array<MyStruct, 3>' is not literal because it has data member '__elems_' of non-literal type 'value_type [3]'
    value_type __elems_[_Size > 0 ? _Size : 1];
5
  • 1
    The error is indicative of the fact that non of the string constructors are constexpr. And how could they be for a type that does dynamic memory allocation? Your table cannot be constexpr if you want to use std::string. Commented May 21, 2017 at 12:25
  • @StoryTeller: Please, do not answer in the comments section. Use the answer section. That's why it's called the answer section. Because .. it's for answers. Commented May 21, 2017 at 12:27
  • @luk32: Technically, but that one is not very good. Commented May 21, 2017 at 12:29
  • 2
    @BoundaryImposition - I'm in the process of scouring for a dup (which I believe exists). Doesn't mean I can't address the error in the OP's thinking. Commented May 21, 2017 at 12:29
  • @BoundaryImposition Than maybe the original should be improved / given better answers. It's essentially the same. Though this one is more about constructor. Not size() method. Commented May 21, 2017 at 12:32

2 Answers 2

1

In C++17 you can use std::string_view instead of std::string. http://coliru.stacked-crooked.com/a/946c48ee9f87a363

For some reason though you can't use the constructor (in string_view) that just takes const char* (it should be possible, because it is constexpr) so it is required to pass length too.

In C++11 it's possible to do the same, but you have to make the std::string_view alike class yourself

Sign up to request clarification or add additional context in comments.

3 Comments

"For some reason though you can't use the constructor that just takes const char* (i should be possible, because it is constexpr)" - No it isn't
@StoryTeller im talking abot string_view
You can use std::string_view_literals to declare the literals {"a"sv, 1, 2}
-1

(migrated from comments section)

The error is indicative of the fact that [none] of the string constructors [are] constexpr. And how could they be for a type that does dynamic memory allocation? Your table cannot be constexpr if you want to use std::string. (user StoryTeller)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.