Topic: An implementation of P0091r0 (class template argument
Author: Faisal Vali <faisalv@gmail.com>
Date: Thu, 21 Jan 2016 22:25:07 -0600
Raw View
Since EWG accepted (mostly? enitrely?) Mike and Richard's proposal
P0091r0 (http://www2.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0091r0.html),
I thought I'd hack together a rough protoype (with some minor additions ;)
to start to get a feel for the feature.
The implementation is at:
https://github.com/faisalv/clang/tree/clang-ctor-deduction
If you choose to read the code, be warned that it is currently quite unkempt
(and requires at least a few hours of refactoring and commenting) and could
be far more efficient (it currently doesn't cache a lot of its repetitive
work) - but it's snowboarding season, so that might just have to wait...
To get an idea of what works and has been tested, the test file is at:
https://github.com/faisalv/clang/blob/clang-ctor-deduction/test/CXX/ctors/cxx1z-ctors.cpp
Of the two syntaxes for their "canonical factory functions" (which I prefer
to refer to as "class template/canonical deducers") I chose the simpler one
to implement - that is "declaration notation", since it required no change
to the parser. Refer to EWG wiki-notes for further thoughts on this issue.
Anyway, I thought I'd share the implementation, with the hope that it helps.
Additionally, while I admit to a strong aversion towards unnecessary
complexity creep,
and would be quite satisfied if Mike and Richard's proposal made its way, as
is, into C++, I could see folks wondering about some potentially related
features, so I thought I'd see what the following would feel like
(Caveat: I do not claim that these sketches are as carefully thought out
as the features in the proposal):
1) Implement deduction through template aliases
template<class T, class Allocator = float*> struct Vec { Vec(T); };
Vec v{1}; // Vec<int, float*>
template<class T> using MyVec = Vec<T, T*>;
MyVec mv{2}; //Vec<int, int*>
I chose to implement this as follows:
- for constructors, by substituting the aliased class template
specialization's template arguments into the synthesized function
templates and using the template parameter list of the alias for deduction
purposes. (obviously only certain aliases will be eligible).
- for deducers (if one is selected via overload resolution), the deducers'
substituted return type must be deducible from the aliased template-id,
or else an error occurs.
2) As we do for function templates, I implemented partial explicit template
arguments that could be extended via deduction.
template<class T> struct A { A(T); };
template<class T, class U> struct B { B(U); };
A<> a{1}; // A<int>
B<int> b{'a'}; //B<int, char>
B<2> b{'a'}; // Error
I turned all the features on by default (for all versions of C++) and ran it
against all the C++ clang regression tests, and asides from having to tweak
some error messages, the illusion of success was maintained.
There are all sorts of assumptions and choices I made (not because I was
convinced they were the right ones, but because I felt I needed to make a
choice to make progress) related to:
- SFINAE when substituting into synthesized constructor templates
(especially when other declarations within the primary class template
might result in a hard error, but the eventual partial specialization
selected might not cause one etc.)
- use of template template parameters and deduction through them
(and their default template arguments (not entirely consistent
with CWG 184)
- contexts where class template argument deduction is allowed
- the interaction with member template aliases
- deducer templates allowed for nested member class templates at class
and namespace scope (and how they interact with SFINAE of the
enclosing class (they don't))
- how and when deducers can be declared and re-declared and made
visible to the deduction process.
- how deducer templates interact with explicitly specified template
arguments.
- limitations on what constitutes a deducer template, and which
template aliases are deducible templates.
- interaction of all deducers with explicit specializations (not complete)
- and many others...
I would be happy to discuss these in more detail if anyone has any questions
directly or indirectly related to them.
Or if you prefer the solitary route, most of the choices can be gleaned
from laboring over the code or perhaps a little more easily from scrutinizing
the test file.
regards,
Faisal Vali
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.