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

Reply via email to