admin管理员组

文章数量:1415100

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

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}}
};
Share Improve this question edited Feb 21 at 23:27 Lance E.T. Compte asked Feb 21 at 0:08 Lance E.T. CompteLance E.T. Compte 1,2191 gold badge16 silver badges40 bronze badges 4
  • If you could catch the exception what would you do with it? Abort the program? That’s exactly what would happen if you didn’t catch it. This seems like an utterly pointless warning. Don’t waste your time on it. – Pete Becker Commented Feb 21 at 1:22
  • I get it Pete, but it's automated... Don't you wanna be me! :-) – Lance E.T. Compte Commented Feb 21 at 1:30
  • 1 In fairness, avoiding dynamic memory allocation during application startup can be a legitimate goal. But that's not because it might throw an exception... – Pete Becker Commented Feb 21 at 14:47
  • @PeteBecker, My edit shows the final code and I do like it much better. No dynamic memory allocation! – Lance E.T. Compte Commented Feb 21 at 16:15
Add a comment  | 

1 Answer 1

Reset to default 2

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

本文标签: cComplex constructor initialization for static const containerStack Overflow