Lance E.T. Compte
Lance E.T. Compte

Reputation: 1209

Complex constructor initialization for static const container

In my header file, within a class body, I declare a vector of tuples where everything is constant. This is just data that I'm going to walk through as I do a task...

class Foo {
 public:
  ...
  static const std::vector<std::tuple<const char*, int>> _data;

In the corresponding source file, I populate the data...

const std::vector<std::tuple<const char*, int>>
Foo::_data
{
  std::make_tuple("One",    1),
  std::make_tuple("Two",    2),
  ...
  std::make_tuple("Many",  10)
};

This throws a clang-tidy error cert-err58-cpp...

/path/to/src/Foo.cpp:783:14: warning: initialization of '_data' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
Foo::_data
     ^
/path/to/gcc-9.2.0/lib/gcc/x86_64-redhat-linux/9.2.0/../../../../include/c++/9.2.0/bits/stl_vector.h:622:7: note: possibly throwing constructor declared here
      vector(initializer_list<value_type> __l,
      ^

I get that there are cases that a vector might not find space to store the data, so would throw an exception. Here, there is no way for me to try/catch it though. That feels overkill for this anyway. What is the best solution here...?

Using std::array instead of std::vector just pushes the problem down to make_tuple...

EDIT: Here is the code that I settled on. No source file additions. This is the header file...

static constexpr std::array<std::pair<const char*, int>, 10> _data {
{
  {{"One",  1},
   {"Two",  2},
   ...
   {"Ten", 10}}
};

Upvotes: 2

Views: 90

Answers (1)

3CxEZiVlQ
3CxEZiVlQ

Reputation: 38863

a vector of tuples where everything is constant

Why not an array of tuples where everything is constant?

class Foo {
 public:
  static const std::array<std::tuple<const char*, int>, 10> _data;
};

const std::array<std::tuple<const char*, int>, 10>
Foo::_data
{{
  {"One",  1},
  {"Two",  2},
  ...
  {"Ten", 10},
}};

With constexpr

class Foo {
 public:
  static constexpr std::array<std::tuple<const char*, int>, 10> _data = {{
    {"One", 1},
    {"Two", 2}
  }};
};

Upvotes: 2

Related Questions