c++ - Idioms for effecively-runtime defined types, domain restrictions on interoperations -
strictly speaking types compile-time constructs in c++. there times constant runtime characteristics of object defined runtime type.
for example, if 1 has geometrical vector, where, due framework restrictions dimension known @ runtime (otherwise make dimension template parameter), example read file.
the fact dimension runtime, doesn't mean 1 should able compare, assign or combine vectors different dimension. if 1 wants introduce logic code, 1 have restrict bunch of operations. can done asserts or throwing, @ runtime.
so, example, 1 implement this,
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
implemented in terms of std::vector
, never change size after construction.
the problem 1 ends writing restriction in functions.
my question if there idioms or facilities can this, restricting (at runtime) operations performed incompatible objects, , in particular helping writing less repeated code.
int v1_dim = 4; int v2_dim = 3; vec v1(v1_dim); // v1 has (forever) dimension 4, 4 essential v1 vec v2(v2_dim); // v2 has (forever) dimension 3 v1 = v2; // logic error, can't prevent compilation of unfortunately; @ least runtime check v1 == v2; // logic error, runtime error
note can't use std::array<double, 4>
or 3>
because 4
, 3
runtime variables.
does concept of effective runtime types has name? has been investigated?
other examples can happen:
1) imagine having variable sized nxn arrays , trying define mathematical addition. n runtime (and constant after construction) , 1 have check 1 not adding arrays of different sizes, 1 incompatible comparison trigger error.
2) more generally, philosophical problem can appear in class constant members. kind of contrived, suppose 1 forced have const
members
struct employee{ std::string const name; // once employee created won't change name double salary; employee& operator=(employee const& other); };
one restrict this:
employee& employee::operator=(employee const& other){ if(name != other.name) throw std::domain_error("cannot change name"); salary = other.salary; return *this; }
the automatic solution imagine systematically overload operator (such operator=() const
) in member types force this.
struct employee{ my_string const name; // once employee created won't change name double salary; employee& operator=(employee const& other){ name = other.name; //simply salary = other.salary; } };
but 1 depends (relies) on special member types with, example:
my_string const& my_string::operator=(my_string const& other) const{ if(*this != other) // "real" inequality (not restricted one), if(this->std::string::operator=(other)) if my_string derived std::string throw std::domain_error("assignment const doesn't preserve value"); return *this; }
and later consistent , systematic 1 write:
employee const& employee::operator=(employee const& other) const{ if(*this != other) throw std::domain_error("assignment const doesn't preserve value"); return *this; }
Comments
Post a Comment