Search code examples
c++c++11try-catchstdarray

C++ Create objects in a try bloc then store them in a std::array


I have a Player object which can throw an exception inside its constructor, so in my main function I'm creating 2 Player objects inside a try block. I want to store these 2 Players in a std::array like that:

try
{
  Player p1(10, 10, ikazuchi);
  Player p2(70, 10, hibiki);
  std::array<Player, 2> players = {p1, p2};
}

The problem is that I wouldn't be able to use the array outside of the try block, and I heard that placing all the main code inside a try block is often a bad idea.

I can't declare my std::array after the try block because p1 and p2 no longer exist there.

I can solve the problem with a std::vector, but I have read that it was better to use a std::array when I know the size of the array during the compilation.

I could create a default constructor to create my objects then fill them inside the try block, but it seems to be more proper to create everything in the constructor.

What would be the best practice for that?


Solution

  • You can always get around issues like this using dynamic allocation or something like boost::optional<std::array<Player, 2>>, but the real question is: should you? That is, assume one of the player objects fails to construct and throws an exception. What will you do with the players array after that? It's not in a legal state, or at least not in the state you'd expect it to be if no exception was thrown.

    There is no problem with having the scope of a try be large. It should cover everything where an exception will prevent you from progressing. If you don't like physically having a lot of source code there, move the code into a function. This might be a good idea anyway: one function which assumes all goes well, and another one whose chief responsibility is to handle errors.

    And if you have meaningful ways of continuing to use players when the objects inside are in an invalid state (constructor threw), then you can just create the array with objects in that state in the first place (outside the try block), and just assign them inside the try.

    The question states you don't want to provide an unneeded default constructor, but I claim that either player belongs inside the try, or Player needs a default constructor (or an equivalent way of expressing "not initialised properly).