Methodenzeiger als Template-Argument - Defaultwerte
-
Hallo da!
Schön, dass ihr wieder da seid.Vielleicht erinnert ihr euch noch an diesen Thread, ich konnte jetzt den Umstand ausnutzen, dass VC++ beim letzten Argument doch den nullptr als default akzeptiert. Zusammen mit decltype sieht das jetzt mMn sehr schön aus, mal davon ab, dass Intellisense darauf abraucht:
#include <iostream> template< typename ValueType, typename ClassType, ValueType(ClassType::*Getter)() const = nullptr > struct getter { static ValueType get(const ClassType* this_) { return (this_->*Getter)(); } static bool is_null() { return Getter == nullptr; } }; template< typename ValueType, typename ClassType, void(ClassType::*Setter)(ValueType) = nullptr > struct setter { template< typename ValInType > static void set(ClassType* this_, ValInType&& val) { (this_->*Setter)(std::forward<ValInType>(val)); } static bool is_null() { return Setter == nullptr; } }; template< typename ValueType, typename ClassType, bool(ClassType::*Validator)(ValueType) const = nullptr > struct validator { static bool validate(const ClassType* this_, const ValueType& val) { if (!is_null()) { return (this_->*Validator)(val); } else { return true; } } static bool is_null() { return Validator == nullptr; } }; template< typename ValueType, typename ClassType, void(ClassType::*Options)() = nullptr > struct options { static void option() {} }; template < typename ValueType, typename ClassType, typename Getter, typename Setter = setter<ValueType,ClassType>, typename Validator = validator<ValueType,ClassType>, typename Options = options<ValueType,ClassType> > struct StaticProperty { ValueType get(const ClassType* this_) { return Getter::get(this_); } template < typename ValTypeIn > void set(ClassType* this_, ValTypeIn&& val) { Setter::set(this_, std::forward<ValTypeIn>(val)); } template < typename ValTypeIn > void validate(ClassType* this_, ValTypeIn&& val) { Validator::validate(this_, std::forward<ValTypeIn>(val)); } private: }; template< typename... Types > struct type_list {}; template< typename Ret, typename Class, typename... Args > struct method_types { using ret_type = Ret; using class_type = Class; using arg_types = type_list<Args...>; }; template< typename ClassType, typename Ret, typename... Args > method_types<Ret, ClassType, Args...> deduce(Ret(ClassType::*arg)(Args...) const); #define StaticPropertyR(Getter) \ StaticProperty< typename decltype(deduce(Getter))::ret_type, typename decltype(deduce(Getter))::class_type, \ getter< typename decltype(deduce(Getter))::ret_type, typename decltype(deduce(Getter))::class_type, Getter > \ > #define StaticPropertyRS(Getter,Setter) \ StaticProperty< typename decltype(deduce(Getter))::ret_type, typename decltype(deduce(Getter))::class_type, \ getter< typename decltype(deduce(Getter))::ret_type, typename decltype(deduce(Getter))::class_type, Getter >, \ setter< typename decltype(deduce(Getter))::ret_type, typename decltype(deduce(Getter))::class_type, Setter > \ > #define StaticPropertyRSV(Getter,Setter,Validator) \ StaticProperty< typename decltype(deduce(Getter))::ret_type, typename decltype(deduce(Getter))::class_type, \ getter< typename decltype(deduce(Getter))::ret_type, typename decltype(deduce(Getter))::class_type, Getter >, \ setter< typename decltype(deduce(Getter))::ret_type, typename decltype(deduce(Getter))::class_type, Setter >, \ validator< typename decltype(deduce(Getter))::ret_type, typename decltype(deduce(Getter))::class_type, Validator > \ > struct test_class { test_class() { } int get_property() const { return value_; } void set_property(int value) { value_ = value; } bool validate(int value) const { return true; } private: int value_; }; StaticPropertyR(&test_class::get_property) my_prop; StaticPropertyRS(&test_class::get_property, &test_class::set_property) my_prop2; StaticPropertyRSV(&test_class::get_property, &test_class::set_property, &test_class::validate) my_prop3; int main() { test_class test; my_prop3.set(&test, 4); std::cout << my_prop3.get(&test); return 0; }