Re: please don't use keyword "where" for the concept facility
Douglas Gregor wrote:
Where does it actually break down, and would a SQL-savvy C++ programmer
(who knows what templates and select statements are, already) consider
taking the analogy that far?
Which analogy? All of the ones that I have seen or imagined to date
break down instantly by utterly failing their purpose, which is to
simplify an explanation. So far, every explanation that I have seen that
uses the sql context is more complex than the explanations that don't.
The point isn't that it is impossible to draw a plausible sql analogy,
but that it is impossible to draw a useful sql analogy.
Demonstrate it to yourself. Explain this code fragment:
template<typename T>
where LessThanComparable<T>
const T & min(const T & l, const T & r);
The syntax from the paper is:
assert Is_Numeric<T>;
assert is another new keyword. If the assert fails, it causes an
immediate error. Hopefully, the diagnostic will indicate which part of
the concept T fails to model.
The "assert" keyword is not used in the latest concepts proposal,
N2042. N2042 is the proposal that we're bringing to the C++ committee.
It is a bit different from earlier proposals, and probably worth a
re-read for those interested:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2042.pdf
Thanks.
It will also help when writing templates, because it will help develop
with developing archetypes.
Archetypes aren't necessary any more.
I wonder about that.
Here's a solution to is_same_template< TYPE, TYPE >. Because the types
that I use it on in the example have archetypes, it also solves
is_same_template< CLASS_TEMPLATE, CLASS_TEMPLATE > for those types.
The archetypes effectively transform the problem from the class template
metaprogramming domain (where metafunction template parameters are class
templates) to the type metaprogramming domain (where metafunction
template parameters are types).
#include <cstddef>
#include <ostream>
using namespace std;
template< typename >
struct
arity1{};
struct
arity1_archetype{};
template< typename, typename >
struct
arity2{};
struct
arity2_archetype0{};
struct
arity2_archetype1{};
template< typename, typename >
struct
is_same_template
{
static const bool value = false;
};
template
<
template< typename > class xT,
typename x0,
typename x1
>
struct
is_same_template< xT< x0 >, xT< x1 > >
{
static const bool value = true;
};
template
<
template< typename, typename > class xT,
typename x0,
typename x1,
typename x2,
typename x3
>
struct
is_same_template< xT< x0, x1 >, xT< x2, x3 > >
{
static const bool value = true;
};
int
main()
{
cout
<<
is_same_template
<
arity1< arity1_archetype >,
arity1< int >
>
::value
<<
endl;
cout
<<
is_same_template
<
arity1< arity1_archetype >,
arity2< int, int >
>
::value
<<
endl;
cout
<<
is_same_template
<
arity2< arity2_archetype0, arity2_archetype1 >,
arity2< int, int >
>
::value
<<
endl;
cout
<<
is_same_template
<
arity2< arity2_archetype0, arity2_archetype1 >,
arity1< int >
>
::value
<<
endl;
}
That solution is fine if I only want to use it on class templates for
which archetypes are dutifully maintained--for example, within my library.
I want to use it in on class templates that originate in application
code too, though, and I'm pretty sloppy about archetypes there. I solved
the problem directly in the class template domain. That solution doesn't
require the archetypes in order to work, but it is no beauty. It took
much MUCH longer to work out than the solution above did. Worse, the
interface to it is awkward.
is_same_template is the only class template domain metaprogramming that
I've needed so far, but it seems likely that I will want to program in
that domain again. I wonder if it will be easier to do in c++0x, and I
wonder if the results will be better.
Complete type-checking for
constrained templates catches all of the errors that archetypes could
catch (and more that archetypes would miss), with much-improved error
messages and less effort on the user's part.
It led me to an actively harmful analogy.
I'm still grasping to understand how it can be harmful.
I've been 30 years before the keyboard, man and boy. I've used SQL since
the mid 80's. I've used c++ since 1991. I've been using templates since
1995. I use enable_if routinely. If anyone was ready to understand what
"where" does with minimal explanation, it was me.
The explanation that I happened to see first left me to invent my own
sql analogy, and I botched the analogy so badly that I misunderstood the
feature. Specifically, I did not grasp the implication of a failed where
clause. I thought it was an error.
If the keyword were enable_if I would have understood it with no
explanation at all. If it were some random string of letters, then I'd
have gotten it right quick.
It's not, though.
Its a sql word.
OMG WHY?????
(Rhetorical ;)
You did better work, and so
arrived at an analogy that is merely useless.
?
It did not help him to understand the feature, which is the only thing
an analogy can do.
As for N1885-6, they were originally meant for a different audience
(academic researchers in programming languages). I expect N2042 will be
much easier reading. As the October C++ committee meeting in Portland
draws closer, we'll provide much more introductory material (tutorials,
presentations, etc.). We would *really* appreciate feedback from
everyone.
Where would I go to find someone's handicapped list of likely changes to
the language?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]