-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];
StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
Jiddoo
  • 1,091
  • 2
  • 9
  • 14
  • 1
    The error is indicative of the fact that [non of the string constructors are constexpr](http://en.cppreference.com/w/cpp/string/basic_string/basic_string). 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`](http://coliru.stacked-crooked.com/a/13333baa0fe123ad). – StoryTeller - Unslander Monica May 21 '17 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. – Lightness Races in Orbit May 21 '17 at 12:27
  • @luk32: Technically, but that one is not very good. – Lightness Races in Orbit May 21 '17 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. – StoryTeller - Unslander Monica May 21 '17 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. – luk32 May 21 '17 at 12:32

2 Answers2

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

Sopel
  • 1,179
  • 1
  • 10
  • 15
-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)

yuri kilochek
  • 12,709
  • 2
  • 32
  • 59
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055