Conditional member initialization

Oct 18, 2014 at 5:45am
Is there a way to still effectively use the member initialization list when there's if-statements inside your constructor? I am doubtful but thought I'd ask anyway.

for example,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Thing {
  public:
    Thing(const std::string& sp)
    {
        if (something_special_about(sp))
        {
            a = 2;
            s = "none";
        }
        else
        {
            a = 0;
            s = sp;
        }
       
    }
  private:
    int a;
    std::string s;
);


In C++11 you can apparently call ctors from other ctors, but by the time you call the other ctor, wouldn't things already be default initialized, defeating the point?
Last edited on Oct 18, 2014 at 6:01am
Oct 18, 2014 at 6:42am
The best way would be to have the 'normal' values for the variable being in the member initializer, and then an if statement inside the body to change it otherwise. As in your example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Thing {
    public:
        Thing(const std::string& sp)
            : _a(0), _sp(sp)
        {
            if (something_special_about(sp)) {
                _a = 2;
                _sp = "none";
            }
        }

    private:
        int _a;
        std::string _sp;
};


As for what's called 'delegating constructors', that involves only if you have multiple constructors that you want to do the same thing for. It removes the need for an init() function or the like. For a small example, see https://isocpp.org/wiki/faq/cpp11-language-classes#delegating-ctor
Oct 18, 2014 at 6:44am
Very elegant solution, thank you!
Oct 18, 2014 at 3:05pm
you can use the ternary operator like so




1
2
3
4
5
6
7
8
9
10
11
class Thing {
public:
    Thing(const std::string& sp):
        a(something_special_about(sp) ? 2 : 0),
        s(a == 2 ? "none" : sp)
    {
    }
private:
    int a;
    std::string s;
};


functionally the same as your code.
Topic archived. No new replies allowed.