This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [c++-concepts] __is_same_as
- From: Andrew Sutton <andrew dot n dot sutton at gmail dot com>
- To: Paolo Carlini <paolo dot carlini at oracle dot com>
- Cc: gcc-patches at gcc dot gnu dot org, Jason Merrill <jason at redhat dot com>, Gabriel Dos Reis <gdr at axiomatics dot org>
- Date: Fri, 26 Jul 2013 09:23:20 -0400
- Subject: Re: [c++-concepts] __is_same_as
- References: <CANq5SysKt1FiRWM1xfpbb2OAmBLJLc2mtNtb_gvmudrk3BZ4_g at mail dot gmail dot com> <51F2687F dot 1030101 at oracle dot com>
> Isn't the name a little misleading? I immediately wondered what was wrong
> with std::is_same. IMHO something a little longer/technical clarifying that
> the trait isn't just about comparing types is in order...
Sure.
First, it means we don't have to instantiate any class templates in
order to decide something as fundamental as type equivalence.
Internalizing the computation should, hypothetically, reduce memory
usage and improve compile times. I haven't tried to write a serious
performance comparison, but that particular benefit should be
self-evident.
Although, as an extension, IMHO, none of the standard type traits
should have library implementations. Many do not. I no longer see any
concrete benefits to writing library implementations of things that
are already known by the compiler.
Second, the intrinsic also provides a canonical name or type
equivalence for constraints. In the purpose of concept checking this
means I have a single definition of the relation (or predicate) to
reason about. Having multiple and different library implementations of
the same fundamental properties (e.g., boost::is_same) makes reasoning
about those properties practically impossible.
For example, in Concepts Lite __is_same_as has a number of built-in
implications. In particular, __is_same_as subsumes __is_convertible_to
and __is_derived_from, which affects the partial ordering of overloads
and partial template specializations (patch forthcoming). Essentially,
that makes this function:
template<typename T, typename U>
requires __is_same_as(T, U)
void f(T, U);
more constrained than this function:
template<typename T, typename U>
requires __is_convertible_to(T, U)
void f(T, U);
IIRC, the algorithms header relies on similar properties for the
optimization of copy or swap. I forget which, specifically.
Without providing an intrinsic, I would have "bless" std::is_same
with special language semantics, which will probably make users wonder
why their trivial implementations of a trivial type trait don't work
the same way. That is to say that boost::is_same would not subsume
boost::is_convertible because that definition hasn't been blessed
with additional semantics.
Concepts lite also uses that canonical name and node to provide
meaningful diagnostics e.g., "T is not the same type as U".
Taking a longer-term view of the problem, internalizing type
equivalence is necessary for separate checking in concepts. In
particular, I rely on these nodes to build a congruence closure over
the template arguments given in template constraints. This effectively
serves the same purpose as the SameType concept from C++0x and its
application as described in n2914 (14.11.1 p3). I don't think that
this would be made easier by relying on library implementations as a
specification of type equivalence.
Andrew