dynamisches static_assert
-
Hallo,
ich habe mir mit Lambdas eine Property Klasse gebastelt. Um eine ReadOnly Property zu haben, lässt man einfach den Setter weg. Bisher prüfe ich nun im = operator ob der Setter 0 ist und werfe, falls ja, eine Exception. Nun frage ich mich, ob sich das ganze auch schon zur Compiletime lösen lässt. static_assert kann ich dazu aber nicht verwenden, weil der Ausdruck nur einmal ausgewertet wird. Der Compiler müsste für mich aber jeden Aufruf des =operators getrennt auswerten.
Gibts es einen Kniff, damit auch sowas möglich ist?greetz KN4CK3R
-
Ohne Code nix los.
-
template<typename ValueType> class Property { public: Property() { } //--------------------------------------------------------------------------- Property(const std::function<ValueType()> &get, const std::function<void(ValueType)> &set) { this->get = get; this->set = set; } //--------------------------------------------------------------------------- ValueType operator = (const ValueType& value) { if (!set) { throw 1; //hier } set(value); return value; } //--------------------------------------------------------------------------- operator ValueType() { if (!get) { throw 1; //und hier } return get(); } //--------------------------------------------------------------------------- private: std::function<ValueType()> get; std::function<void(ValueType)> set; };greetz KN4CK3R
-
Wo soll denn der Setter hinsetten? Und woraus soll der Getter lesen?
-
Irgendwie anders mit Templatespezialisierung vielleicht?
So:template<typename ValueType> class write_extend { public: typedef ValueType type; typedef std::function<void (type)> setter_functor; write_extend(setter_functor const & setter) : m_setter(setter) {} type operator = (type const & value) { m_setter(value); return value; } private: setter_functor m_setter; }; template<typename ValueType> class read_extend { public: typedef ValueType type; typedef std::function<type ()> getter_functor; explicit read_extend(getter_functor const & getter) : m_getter(getter) { } operator type() { return m_getter(); } private: getter_functor m_getter; }; struct read_only_property{}; struct read_write_property{}; template<typename ValueType, typename AccessTag = read_write_property> class property; template<typename ValueType> class property<ValueType, read_write_property> : public read_extend<ValueType> , public write_extend<ValueType> { typedef read_extend<ValueType> read_base; typedef write_extend<ValueType> write_base; public: property(getter_functor const & getter, setter_functor const & setter) : read_base(getter) , write_base(setter) { } using read_base::operator read_base::type; using write_base::operator=; }; template<typename ValueType> class property<ValueType, read_only_property> : public read_extend<ValueType> { typedef read_extend<ValueType> read_base; public: property(getter_functor const & getter) : read_base(getter) { } using read_base::operator read_base::type; }; //Benutzung: //hat nur setter und kann nur gelesen werden property<int, read_only_property> p1(&get_fct); //compile fehler: kein setter setzbar property<int, read_only_property> p2(&get_fct, &set_fct); //lesen und schreiben erlaubt property<int> p3(&get_fct, &set_fct); //compile fehler: p1 hat kein operator= p1 = 42; //okay std::cout << p1 << std::endl; //okay p3 = 42; //okay std::cout << p3 << std::endl;Ob das ganze überhaupt sinnvoll ist, sei mal dahingestellt...
-
Michael E. schrieb:
Wo soll denn der Setter hinsetten? Und woraus soll der Getter lesen?
dazu übergibt man ja den entsprechenden Getter bzw Setter.
@Tachyon: ok, das wäre ein Möglichkeit, danke
greetz KN4CK3R
-
Wie wäre es ganz banal mit einer
ReadOnlyPropertyKlasse?Grüssli
-
geht natürlich, eine "ist ReadOnly" Meldung beim Compilieren hätte mir persönlich allerdings besser gefallen.
greetz KN4CK3R
-
KN4CK3R schrieb:
geht natürlich, eine "ist ReadOnly" Meldung beim Compilieren hätte mir persönlich allerdings besser gefallen.
class read_only_property { public: read_only_property& operator =(int value) { static_assert(false, "property is readonly"); } }; int main() { read_only_property p; p = 10; return 0; }Noch ein Wunsch?
Grüssli
-
nein, passt
