有效运行时定义类型的习惯用法,对互操作的域限制 严格地说,类型是C++中编译时的构造。 但是,有时对象的某些常量运行时特征被有效地定义为运行时类型

有效运行时定义类型的习惯用法,对互操作的域限制 严格地说,类型是C++中编译时的构造。 但是,有时对象的某些常量运行时特征被有效地定义为运行时类型,c++,runtime-error,subtyping,runtime-type,C++,Runtime Error,Subtyping,Runtime Type,例如,如果有一个几何向量,其中,由于框架限制,维度仅在运行时已知(否则我会将维度设置为模板参数),例如从文件读取 维度是运行时的这一事实并不意味着人们应该能够比较、分配或组合具有不同维度的向量。 如果要将此逻辑引入代码中,必须限制一系列操作。 这可以通过断言或抛出来完成,仅在运行时进行 那么比如说,要实施这个, class vec{ std::vector<double> impl_; public: vec(std::size_t size) : impl_

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

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

那么比如说,要实施这个,

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;
    }
};
请注意,我不能使用
std::array
3>
,因为
4
3
可能是运行时变量

有效运行时类型的概念有名称吗?有没有调查过


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

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;
}
employee const& employee::operator=(employee const& other) const{
    if(*this != other) throw std::domain_error("assignment to const doesn't preserve value");
    return *this;
}