Успех наконец-то! http://ideone.com/XJ7of
Эта немного лучшая версия работает только на Comeau (не уверен, что Comeau или gcc верны, но gcc жалуется на обозначение friend
).
#include <iostream>
#include <typeinfo>
template <class T, class X,void (T::type::*setFunc)(const typename X::type&),const typename X::type& (T::type::*getFunc)()const> class property_impl
{
typename T::type* const owner;
friend typename T::type;
property_impl(typename T::type* const pOwner) : owner (pOwner)
{
}
public:
property_impl& operator = (const typename X::type& input){(owner->*setFunc)(input); return *this;}
operator const typename X::type&()const {return (owner->*getFunc)();}
};
template<typename T> struct identity { typedef T type; };
template<typename Arg, typename T>
identity<T> match_memfn_classtype( void (T::*fn)(Arg) );
template<typename Arg, typename T>
identity<Arg> match_memfn_argtype( void (T::*fn)(Arg) );
#define property(setter,getter) property_impl<decltype(match_memfn_classtype(setter)), decltype(match_memfn_argtype(setter)), setter, getter>
struct C
{
private:
int hiddenData;
protected:
void setInt(const int& data) { hiddenData = data; std::cout << "setter used\n"; }
const int& getInt() const { std::cout << "getter used\n"; return hiddenData; }
public:
C() : myInt(this), hiddenData(5) {}
property(&C::setInt,&C::getInt) myInt;
};
int main(void)
{
C c;
std::cout << "c.myInt = " << c.myInt << '\n';
c.myInt = -1;
std::cout << "c.myInt = " << c.myInt << '\n';
return 0;
}
И VC ++ 2010 подавляет все варианты, хотя он работает для очень простого использования match_memfn_classtype
.
Подано сообщение об ошибке (пожалуйста, проголосуйте):
Компилятор C ++ теряет членство функции указателя на член во время вывода шаблона, вызывает ICE
Microsoft обновила отчет об ошибках, чтобы сообщить, что они нашли исправление.