有效运行时定义类型的习惯用法,对互操作的域限制 严格地说,类型是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;
}