1

严格来说,类型是 C++ 中的编译时构造。然而,有时对象的一些常量运行时特性被有效地定义为运行时类型。

例如,如果有一个几何向量,其中,由于框架限制,尺寸仅在运行时已知(否则我会将尺寸设为模板参数),例如从文件中读取。

维度是运行时这一事实并不意味着应该能够比较、分配或组合具有不同维度的向量。如果想在代码中引入这种逻辑,就必须限制一堆操作。这可以通过断言或抛出来完成,仅在运行时。

所以,例如,一个人会实现这个,

class vec{
    std::vector<double> impl_;
    public:
    vec(std::size_t size) : impl_(size){}
    bool operator==(vec const& other) const{
        if(impl_.size() != other.impl_.size()) throw std::domain_error("cannot compare vectors of different size");
        return std::equal(impl_.begin(), impl_.end(), other.impl_.begin());
    }
    bool operator<(vec const& other) const{
        if(impl_.size() != other.impl_.size()) throw std::domain_error("cannot compare vectors of different size");
        return impl_ < other.impl_;
    }
    vector& operator=(vector const& other){
        if(impl_.size() != other.impl_.size()) throw std::domain_error("");
        std::copy(other.impl_.begin(), other.impl_.end(), impl_.begin());
        return *this;
    }
};

vec实施std::vector后尺寸不会改变。

这样做的问题是,最终会在所有函数中编写限制。

我的问题是,是否有任何习惯用法或工具可以通过限制(在运行时)使用不兼容对象执行的操作,特别是帮助编写更少重复的代码来帮助解决这个问题。

int v1_dim = 4;
int v2_dim = 3;
vec v1(v1_dim); // v1 has (forever) dimension 4, 4 is essential to v1
vec v2(v2_dim); // v2 has (forever) dimension 3
v1 = v2; // this is a logic error, I can't prevent the compilation of this unfortunately; So I will at least do a runtime check 
v1 == v2; // this is a logic error, runtime error

请注意,我不能使用std::array<double, 4>or3>因为4and3可能是运行时变量。

这个有效运行时类型的概念有名字吗?有没有被调查?


可能发生这种情况的其他示例:

1) 想象一下拥有可变大小的 NxN 数组并尝试定义数学加法。N 将是运行时的(甚至在构造后是常数),并且必须检查一个人没有添加不同大小的数组,还希望任何不兼容的比较都会触发错误。

2) 更一般地说,这个哲学问题可以出现在具有固定成员的类中。这有点做作,但假设一个人被迫拥有const成员

struct employee{
    std::string const Name; // Once the employee is created it won't change name
    double salary;
    employee& operator=(employee const& other);
};

可以限制这一点:

employee& employee::operator=(employee const& other){
    if(Name != other.Name) throw std::domain_error("cannot change name");
    salary = other.salary;
    return *this;
}

我想象的唯一自动解决方案是系统地重载成员类型中的某些运算符(例如operator=() const)以强制执行此操作。

struct employee{
    My_string const Name; // Once the employee is created it won't change name
    double salary;
    employee& operator=(employee const& other){
         Name = other.Name; //simply
         salary = other.salary;
    }
};

但是其中一个取决于(依赖)特殊成员类型,例如:

My_string const& My_string::operator=(My_string const& other) const{
    if(*this != other) // this is the "real" inequality (not the restricted one), probably it will be if(this->std::string::operator=(other)) if My_string is derived from std::string
        throw std::domain_error("assignment to const doesn't preserve value");
    return *this;
}

后来为了保持一致和系统,人们会写:

employee const& employee::operator=(employee const& other) const{
    if(*this != other) throw std::domain_error("assignment to const doesn't preserve value");
    return *this;
}
4

0 回答 0