compile-time cost of alias templates
Jonathan Wakely
jwakely.gcc@gmail.com
Sun Dec 18 23:10:00 GMT 2011
On 18 December 2011 22:41, Gabriel Dos Reis wrote:
> On Sun, Dec 18, 2011 at 11:38 AM, Jason Merrill <jason@redhat.com> wrote:
>> On 12/18/2011 11:00 AM, Jonathan Wakely wrote:
>>>
>>> Currently in<functional> we have this helper class to constrain the
>>> std::bind function template via SFINAE:
>>>
>>> template<typename _Tp>
>>> class __is_socketlike
>>> {
>>> typedef typename decay<_Tp>::type _Tp2;
>>> public:
>>> static const bool value =
>>> is_integral<_Tp2>::value || is_enum<_Tp2>::value;
>>> };
>>>
>>> I was going to replace the static member with:
>>> static const bool value = __or_<is_integral<_Tp2>,
>>> is_enum<_Tp2>>::value;
>>>
>>> But now that we have alias templates I'm wondering if it would be
>>> better to write it as:
>>>
>>> template<typename _Tp>
>>> using __is_socketlike
>>> = __or_<is_integral<typename decay<_Tp>::type>,
>>> is_enum<typename decay<_Tp>::type>>;
>>>
>>>
>>> Does the implementation in G++ mean that using an alias template
>>> avoids instantiating the separate __is_socketlike class template, or
>>> is there just as much cost in instantiating an alias template as a
>>> class template?
>>
>>
>> Instantiating an alias is simpler, aliases are basically transparent.
>
> Yes; at some point we are planning to publish "memory usage" numbers
> based on existing practice.
That will be very interesting.
>> However, this change would mean that any mangling exposure of
>> __is_socketlike would change. But that may not be an issue since it's an
>> internal type.
>>
>> Jason
>
> Agreed.
> Jonathan, note however that neither the original code nor the new version does
> short-circuiting of instantiations.
The original code using || (i.e. whats currently used in libstdc++)
instantiates is_enum<_Tp2> unconditionally. The version above using
__or_ avoids that instantiation when is_integral<Tp2> is true, and
from my brief experiments the alias template appears to avoid
instantiating it too - am I missing something?
I did see the ext reflector discussion about alias templates not doing
"lazy" instantiations when used in certain ways, but I don't think
that's relevant here because I don't refer to a member of is_integral
or is_enum within the alias template:
template<typename _Tp, typename _Tp2 = typename decay<_Tp>::type>
using __is_socketlike = __or_<is_integral<_Tp2>, is_enum<_Tp2>>;
I'm not really concerned about an extra instantiation of is_enum as
that's a very small template, but it's good to know that alias
templates are transparent and simpler. I've found a few good uses for
them already.
More information about the Libstdc++
mailing list