用相同的参数将内部和外部构造函数分开



i有一种具有值的类型,将其按照类型的参数进行检查,从那时起,该值允许该值以不变性为单位。该类型还具有与之相关的许多操作,这些操作创建了该类型的新值。所有这些操作都是定义的,因此不需要检查。一旦用户的价值在类型的类型中都无法使用该类型的无效值。

我需要的是两个构造函数:一个内部和一个外部。外部构造函数应执行检查,而内部构造函数则不应执行。否则它们具有相同的参数,唯一的区别是检查,这是主要问题。出于绩效原因,避免了支票。以下是一个模拟的例子。

#include <stdexcept>
template <int limit>
class ClippedValue;
template <int limit>
void check(ClippedValue<limit> v) {
    if (std::abs(v.value) > limit) {
        make_user_solve_P_eq_NP();
        throw std::range_error("Given value exceeds available range");
    }
}
template <int limit>
class ClippedValue {
public:  // external constructor
    constexpr ClippedValue(int a) : value(a) { check(*this); }
private:  // internal constructor
    constexpr ClippedValue(int a) : value(a) {}
public:  // members
    const int value;
public:  // friends
    template <int A, int B>
    friend constexpr ClippedValue<A + B> operator+ (ClippedValue<A> a, ClippedValue<B> b);
}
template <int A, int B>
constexpr ClippedValue<A + B> operator+ (ClippedValue<A> a, ClippedValue<B> b) {
    return a.value + b.value;
}

上面没有编译,两个构造函数是相同的。

上面没有编译,两个构造函数是相同的。

确实。如此区分它们。

enum class unchecked_t {};
constexpr ClippedValue(unchecked_t, int a) : value(a) {}

标准库本身经常使用此范式。它区分了过载,并且由于unchecked_t及其种类可能会自行访问控制,因此可以使用更精细的粒度可访问性规范,例如使用密钥 - 通用习惯。

正如您已经发现的那样,您不能有两个具有相同接口的构造函数。

您可以将一个虚拟参数添加到第二个构造函数中,以将其与第一个构造函数区分开。

template <int limit>
class ClippedValue
{
   public:
      // external constructor
      constexpr ClippedValue(int a) : value(a) { check(*this); }
   private:
      // A type that can be used only internally and by friends of the class.
      struct internal {};
      // internal constructor. An overload.
      // Use another argument, of type internal.
      constexpr ClippedValue(int a, internal) : value(a) {}
      ...
};

最新更新