On 02/13/2016 03:14 PM, John Ralls wrote: > >> On Feb 13, 2016, at 12:25 PM, Larry Evans <cppljev...@suddenlink.net> wrote: >> >> >> >> On 02/13/2016 01:03 PM, John Ralls wrote: >> [snip] >>> You started out trying to encapsulate an object and a flag that >> indicated where to put it. That had genericity problems because there's >> no type-safe way to generically handle the differing return types. >> Polymorphism to the rescue! Except that it turns out that you have >> different handling requirements depending not on the type that you're >> storing but on the actual property that you're processing. >>> >>> How about this: >>> template <typename T, GncTransPropType p> class GncTransPropImpl { >>> public: >>> GncTransPropImpl (T v) : value {v} {} >>> ... >>> friend template<>void >> set_property(std::unique_ptr<GncTransPropImpl<T, P>> prop, Transaction >> *txn); >>> friend template<>void >> set_property(std::unique_ptr<GncTransPropImpl<T, P>> prop, Split *split); >>> private: >>> T value; >>> } >> >> Why not make T a metafunction of p? IOW, define: >> >> template<GncTransPropType Index> >> struct PropIndex2PropType >> ; >> >> template<> >> struct PropIndex2PropType<ACCOUNT> >> { >> using Type = Account*; >> }; >> template <GncTransPropType p> class GncTransPropImpl { >> public: >> using T = typename PropIndexPropType::type; >> GncTransPropImpl (T v) : value {v} {} >> ... >> private: >> T value; >> }; >> >> That way one template argument is avoided. >> You could also just define a typelist using >> maybe boost::mpl::vector<T0,T1,T2,...> >> and index into that instead of using PropIndex2PropType. >> > > Nice. I haven't seen that use of 'typename' before, but I'm still a beginner > at metaprogramming. What does it actually do there? IOW, what's the > difference between 'using T = PropIndex2PropType::Type' and 'using T = > typename PropIndex2PropType::Type'? >
Without it you get a compile error. IIUC, It's only needed within templates. When I compile the attached, which doesn't use typename, I get the error: ident_meta.cpp:9:13: error: need ‘typename’ before ‘ident1<T>::type’ because ‘ident1<T>’ is a dependent scope using T = ident1<T>::type; ^ HTH. -rega > Using boost::mpl::vector could also replace the abstract superclass at the > expense of having to explicitly list all of the GncTransPropImpl > specializations in its declaration. > > Aside: I'm a bit leery of using too much metaprogramming in GnuCash. While > the gurus (Sutter, Myers, et. al.) have been promoting it for the last > several years it seems to be pretty esoteric still and it might be too > incomprehensible to most potential contributors. > I understand. I still have difficulty with metaprogramming. > Regards, > John Ralls >
template<typename T> struct ident1 { using type=T; }; template<typename T> struct ident2 { using T = ident1<T>::type; }; int main() { ident2<int>::type i=0; return i; }
_______________________________________________ gnucash-devel mailing list gnucash-devel@gnucash.org https://lists.gnucash.org/mailman/listinfo/gnucash-devel