4
#include <iostream>
#include <string>
#include <cassert>

struct Foo
{
  std::string bar = "standard";
  int x = 1;
  int y = 1;

  bool operator==(const Foo&) const = default;
  bool operator!=(const Foo&) const = default;

  void ResetToStandard()
  {
    bar = "standard";
    x = 1;
    y = 1;
  }  
};

int main(int argc, char* argv[])
{
  Foo f, g;
  g.bar = "Hello world!";
  g.x = 123;
  g.y = 234;
  g.ResetToStandard();
  assert(f == g);
}

In this sample code (very simplified real world code) I have a struct Foo whose fields have default values. There is also a ResetToStandard function that sets all field to their standard value, but all the values are repeated in this function.

Then I came up with this, which works fine.

void ResetToStandard()
{
  *this = Foo();
}

Is this pattern common? Is this the idiomatic way?

7
  • Not sure what is the best/idiomatic way, but you can remove the initializers from the members declarations, and call ResetToStandard() from a default ctor. Commented Jun 6 at 11:28
  • 2
    What do you expect about capacity of members (as std::string/std::vector)? manual reinitialization might kept the capacity, whereas assigning from new object will re-init capacity too. Commented Jun 6 at 11:29
  • @Jarod42 good point. Commented Jun 6 at 11:42
  • 6
    Is this pattern common? It is the pattern I'd use. I do not use it commonly, because resetting an object to an initial state is not something I commonly need to do. It is idiomatic enough that my only point of concern is whether it is better to have a ResetToStandard() method or to have the callsite itself just do g = Foo{};. The method makes sense for a polymorphic class hierarchy. Commented Jun 6 at 11:58
  • 1
    @wohlstad Note that this can result in less efficient machine code for the default constructor (bar will be first default-initialized and then assigned-into): godbolt.org/z/xvrq4c68q. Commented Jun 6 at 13:40

1 Answer 1

5

I would use *this = {} like this (to reassign this from default constructed object).
Which should use the move constructor.

#include <iostream>
#include <string>
#include <cassert>

struct Foo
{
    std::string bar = "standard";
    int x = 1;
    int y = 1;

    bool operator==(const Foo&) const = default;
    bool operator!=(const Foo&) const = default;

    void ResetToStandard()
    {
        *this = {};
    }
};

int main(int argc, char* argv[])
{
    Foo f, g;
    g.bar = "Hello world!";
    g.x = 123;
    g.y = 234;
    g.ResetToStandard();
    assert(f == g);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.