Til
Til

Reputation: 11

RAII std::vector design conundrum

I’m not a fan of classes like the one below that have an IsValid() function, because you have to remember to check IsValid() everywhere:

struct BadTextWidget
{
    BadTextWidget(const std::string & TEXT) : m_text(TEXT) {}
    bool IsValid() const;
    ...

I prefer the RAII approach which makes it impossible to construct an invalid object:

struct BetterTextWidget
{
    BetterTextWidget(const std::string & TEXT) : m_text(TEXT)
    {
        if (IsValid(m_text) == false) throw std::invalid_argument("...");
    }
    ...

However, I also like using vectors, but that requires constructor arguments to have default values which are not going to be valid. This forces me to use BadTextWidget again.

So how do you get the performance characteristics of std::vector with validating constructors that throw? How do you resolve this design conundrum? What am I missing?

Upvotes: 0

Views: 465

Answers (1)

Alan Birtles
Alan Birtles

Reputation: 36399

until c++11 vector elements needed to be copyable, since c++11 the requirements depend on which methods you use. In general any class which is movable should work with most vector operations. Operations like resize() still require default constructibility if you don't supply a default value.

e.g.

std::vector< BetterTextWidget > vector( 20 );

won't work but:

std::string str;
std::vector< BetterTextWidget > vector( 20, BetterTextWidget( str ) );

will

Upvotes: 2

Related Questions