C++ 如何防止初始值设定项列表中出现错误值?

C++ 如何防止初始值设定项列表中出现错误值?,c++,constants,initializer-list,valueerror,C++,Constants,Initializer List,Valueerror,在编写构造函数时,您有机会在其主体中测试超出范围或其他不需要的情况下的参数值 class a { int b; public: a(int c) { if(c < MIN_ALLOWED || c > MAX_ALLOWED) { // Take some measure } else { b = c; } } }; 您可以将变量的验证和修改委托给函数 class a { public:

在编写构造函数时,您有机会在其主体中测试超出范围或其他不需要的情况下的参数值

class a
{
  int b;
public:
  a(int c)
  {
    if(c < MIN_ALLOWED || c > MAX_ALLOWED)
    {
      // Take some measure
    }
    else
    {
      b = c;
    }
  }
};

您可以将变量的验证和修改委托给函数

class a {
 public:
  a(int c) : b(ValidateAndTransformInputParameter(c)) {}
 private:
  const int b;
  int ValidateAndTransformInputParameter(int d) const {
    if (d < 100) {
      d = 100;
    }
    return d;
  }
};

您可以将变量的验证和修改委托给函数

class a {
 public:
  a(int c) : b(ValidateAndTransformInputParameter(c)) {}
 private:
  const int b;
  int ValidateAndTransformInputParameter(int d) const {
    if (d < 100) {
      d = 100;
    }
    return d;
  }
};
制作一个函数:

class a {
    int const b;

public:
    a(int const c)
        : b { initializeB(c) }
    {
    }

private:
    static int initializeB(int const c)
    {
        if (c < MIN_ALLOWED || c > MAX_ALLOWED) {
            // Take some mesure
            return -1; // example
        }
        return c;
    }
};
a(int c) : b(process(c)) {}
制作一个函数:

class a {
    int const b;

public:
    a(int const c)
        : b { initializeB(c) }
    {
    }

private:
    static int initializeB(int const c)
    {
        if (c < MIN_ALLOWED || c > MAX_ALLOWED) {
            // Take some mesure
            return -1; // example
        }
        return c;
    }
};
a(int c) : b(process(c)) {}

主要有三种方式:

使用逗号运算符链接验证:

a(int c) : b(validate(c), c) {}
a(int c) : b(validate(c) ? c : throw 0) {}
请记住,初始值设定项严格按照声明顺序深度优先执行,忽略虚拟继承

使用三元运算符:

a(int c) : b(validate(c) ? c : throw 0) {}
如果这真的是一次性的,就需要最少的folderol

使用转换和验证类或函数:

class a {
    int const b;

public:
    a(int const c)
        : b { initializeB(c) }
    {
    }

private:
    static int initializeB(int const c)
    {
        if (c < MIN_ALLOWED || c > MAX_ALLOWED) {
            // Take some mesure
            return -1; // example
        }
        return c;
    }
};
a(int c) : b(process(c)) {}
或者,它们可以与ctor链接相结合,特别是当处理输入时产生多个结果时:

private:
    struct process {
        ...
    };
    a(process x) : b(x.b), c(x.c), d(x.d) {}
public:
a(int c) : a(process(c)) {}

主要有三种方式:

使用逗号运算符链接验证:

a(int c) : b(validate(c), c) {}
a(int c) : b(validate(c) ? c : throw 0) {}
请记住,初始值设定项严格按照声明顺序深度优先执行,忽略虚拟继承

使用三元运算符:

a(int c) : b(validate(c) ? c : throw 0) {}
如果这真的是一次性的,就需要最少的folderol

使用转换和验证类或函数:

class a {
    int const b;

public:
    a(int const c)
        : b { initializeB(c) }
    {
    }

private:
    static int initializeB(int const c)
    {
        if (c < MIN_ALLOWED || c > MAX_ALLOWED) {
            // Take some mesure
            return -1; // example
        }
        return c;
    }
};
a(int c) : b(process(c)) {}
或者,它们可以与ctor链接相结合,特别是当处理输入时产生多个结果时:

private:
    struct process {
        ...
    };
    a(process x) : b(x.b), c(x.c), d(x.d) {}
public:
a(int c) : a(process(c)) {}

以上所有答案都是好的,而且很有效。。。但为了避免我们忘记,你也可以这样做:

class a
{
    public:
        a(int c) : b([=]() -> int {
            if (c < MIN_ALLOWED || c > MAX_ALLOWED)
                throw std::logic_error("b");
            return c;
        }()) {}
    private:
        int b;
})


但在我看来,在初始值设定项列表中有一个lambda看起来很糟糕,但这仍然是可能的。

以上所有答案都很好,而且很有效。。。但为了避免我们忘记,你也可以这样做:

class a
{
    public:
        a(int c) : b([=]() -> int {
            if (c < MIN_ALLOWED || c > MAX_ALLOWED)
                throw std::logic_error("b");
            return c;
        }()) {}
    private:
        int b;
})


在我看来,在初始值设定项列表中使用lambda看起来很糟糕,但这仍然是可能的。

可以在初始化器列表中使用三元运算符来测试分配给const成员的值。但是,应避免在类中使用const成员。它不适用于大多数STL,通常很难使用。您可以使用初始化器列表中的三元运算符来测试分配给常量成员的值。但是,应避免在类中使用const成员。它不适用于大多数STL,通常很难使用。