在声明(运行 次)后创建一个 Class 变量常量(使用一些 class 方法)

Make a Class variable const after declaration (run time) (with some class method)

我有一个模板:

template<typename T>
struct Parameter {

    T value;
    std::string name;

    Parameter(std::string name, T value) : name(name), value(value){}
    void fix() {
        // Fix this->value (make this->value const)
    }
    void print() { std::cout << value << std::endl; }
};

并且我想在初始化后的某个时候 'const-ify' 值变量

std::string name = "variance";
double var = 1.0;
Parameter<double> variance(name, var);
variance.print();
variance.fix();
variance.value = 2.3; // Not Allowed, throws error

是否可以这样做以及如何做到?

如果你想维护相同的接口,并且通过访问器编组访问 value 是你想要避免的事情,那么你可以将“可修复”功能隔离在它自己的专用类型中,隐式转换 to/from T:

template<typename T>
class fixable {
  bool fixed_ = false;
  T val_;

public:
  fixable() = default;
  fixable(T v) : val_(v) {}
  fixable(const fixable&) = default;
  fixable(fixable&&) = default;
  
  operator const T&() const { 
    return val_;
  }

  fixable& operator=(const T& v) {
    if(fixed_ ) {
      throw std::runtime_error("Fixable has been fixed");
    }

    val_ = v;
    return *this;
  }

  void fix() {
    fixed_ = true;
  }
};

然后您可以用 Parameter:

中的 fixable<T> 替换 T 成员
template<typename T>
struct Parameter {

    fixable<T> value;
    std::string name;

    Parameter(std::string name, T value) : name(name), value(value){}
    void fix() {
      value.fix();
    }
    void print() { std::cout << value << std::endl; }
};

您问题中的主要功能可以保持原样。

你可以这样使用: 类似于 abowe answer 但在参数 struct

中带有布尔值
template<typename T>
struct Parameter {
    Parameter(std::string name, T value) : name(name), value(value), bFixed(false) {}
    void fix() {
        bFixed = true;
    }
    void print() { std::cout << value << std::endl; }

    Parameter& operator=(const T& oValue)
    {
        if (bFixed)
        {
            throw std::runtime_error("Error fixed value..");
        }

        value = oValue;
        return *this;
    }

    std::string name;

private:
    bool bFixed;
    T value;
};

int main()
{
    std::string name = "variance";
    double var = 1.0;
    Parameter<double> variance(name, var);
    variance.print();
    variance.fix();
    variance = 2.3; // Not Allowed, throws error
}

您不能将成员变量从 const 更改为非常量。但是,您可以创建一个新对象,其中它是 const。例如:

template<typename T>
struct example {
    T value;

    example<T const> fix() && {
        return {value};
    }
};

int main(){
    auto x = example<int>{1};
    x.value = 4; // OK
    auto y = std::move(x).fix();
    y.value = 7; // error: assignment of read-only member
}

&& 的存在强制使用 std::move,这显然不应再使用 x