From 1050700043933600083
X-Google-Thread: f78e5,c4ab463952a444d1
X-Google-NewGroupId: yes
X-Google-Attributes: gid7894ca11fe,domainid0,public,usenet
X-Google-Language: ENGLISH,ASCII-7-bit
Path: g2news1.google.com!news1.google.com!npeer02.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!Xl.tags.giganews.com!border1.nntp.dca.giganews.com!nntp.giganews.com!local2.nntp.dca.giganews.com!news.giganews.com.POSTED!not-for-mail
NNTP-Posting-Date: Mon, 19 Jul 2010 17:30:22 -0500
Return-Path: <cppmods@ruralroute.cs.rpi.edu>
To: (Usenet)
From: =3D?ISO-8859-1?Q?Daniel_Kr=3DFCgler?=3D <daniel.kruegler@googlemail.c=.om>
Newsgroups: comp.std.c++
Subject: Re: SFINAE anomaly
Organization: http://groups.google.com
Sender: cppmods@cs.rpi.edu
Approved: austern@google.com
Message-ID: <94198f77-7de0-4009-bc94-d41a608bb7ee@w12g2000yqj.googlegroups.com>
References: <i1r4g1$uqa$1@news.eternal-september.org>
 <b05afe8b-3962-4bbf-8efc-1ebbc40063d9@t10g2000yqg.googlegroups.com>
 <i1vvqm$2r6$1@news.eternal-september.org>
Content-Type: text/plain; charset=windows-1252
X-Original-Date: Mon, 19 Jul 2010 12:05:55 -0700 (PDT)
X-Submission-Address: std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.e=
	du>
Date: Mon, 19 Jul 2010 17:21:05 CST
Lines: 215
X-Usenet-Provider: http://www.giganews.com
X-Trace: sv3-qKxGzduXq4TA6Ejbzfmk0n/5ScSo7trRU+xHQ+hHSHAlZ5apejaaM8ihz91xf5wZ+rJKOEExA8bv8cN!bkHGDk0StjiGLhBc9vK7FJenwY/2j8ix1Thlx/U1uoLq5sRCmBSme03m6OvkUYgSWdmwlHeFTOgv!0POzXboXJ70wCJFsHR7ykmo0sVw=
X-Complaints-To: abuse@giganews.com
X-DMCA-Notifications: http://www.giganews.com/info/dmca.html
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
X-Postfilter: 1.3.40
Xref: g2news1.google.com comp.std.c++:2783

On 19 Jul., 20:19, Edward Diener <eldie...@tropicsoft.invalid> wrote:
> On 7/18/2010 5:27 PM, Daniel Kr=FCgler wrote:
>
> > I think this is clearly a compiler defect.
>
> Is it a compiler defect under the C++03 compiler using SFINAE, or are
> you saying it is a compiler defect under the C++0x extended SFINAE ? If
> it is a compiler defect only under the C++0x extended SFINAE then it is
> quite possible that the three versions of compilers I have tested this
> under do not yet implement the C++0x extended SFINAE.

I ignored C++03 in my discussion because you already mentioned
"extended SFINAE" rules, which are not available within C++03.
Looking at the C++03 rules I would say that the wording is not
really clear here. A weak interpretation of 14.8.2/2 would include
your example, a strong interpretation would not. The part of the
wording which can be interpreted to apply is bullet 2:

=97 The specified template arguments must match the template
parameters in kind (i.e., type, nontype, template), and there must
not be more arguments than there are parameters; otherwise type
deduction fails.

The problem with the C++03 wording is that it describes are
individual deduction failure cases in a long sub-bullet list below
bullet 3. Your particular situation is not part of the list.
The difference in C++0x is, that the individual list is gone and
the rule is no simply that only types (and expressions) in the
"immediate context" occurring in the function signature (return
type, parameters) are considered. I described that in a lax
way as "top-level types".

> > The new rules clearly say that a invalid type occurring on top
> > level has to be silently ignored.
>
> The phrase "invalid type occurring on top level" appears to be yours,
> and not in the working draft for the standard.

Sure, it was just a non-normative description of the normative
wording that I quoted later.

> > This is essentially satisfied
> > for your snippet. Situations which are *not* covered, are
> > those where instantiation errors occur *within* the type - this
> > doesn't happen here.
>
> I admit I was following the topic athttp://
www.boostcon.com/community/wiki/show/ExtendedSFINAE/, and not
> attempting to understand what the working draft of the C++0x standard
> says, where my search for SFINAE yielded nothing.

Exactly, similar to my "top-level-type" wording, the term SFINAE does
not officially exist in the standard, but it nonetheless became a
non-normative technical term in C++ discussions (and your thread
title contains this non-normative term as well).

> It is explained at that web page that the one of the differences between
> the previous way that SFINAE worked is that "the extended SFINAE rules
> of C++0x generalize SFINAE to work with arbitrary expressions", where I
> did not think that "typename U1::template M<U2, U3>*" was such an
> expression; and where it says that:
>
> 'There are two classes of errors for which SFINAE still does not apply:
>
>     1. If the type-checking failure is due an access violation (e.g., x
> + y resolves to a private operator+), that error is a "hard" error that
> does not invoke SFINAE.

Correct (and we don't have it in your example).

>     2. If the type-checking failure occurs within the instantiation of a
> class template or in the body of a function template, that error is a
> "hard" error that does not invoke SFINAE.'

Also correct. A simple example for such a "hard error" can be
constructed, if we change my revised example as follows:

struct A {
 template <class T>
 struct M {
   M(int, T = T()){}
 };
};

template<class T1, class T2 = void>
struct B {
 template<class U1, class U2>
 static char test(typename U1::template M<U2>);

 template<class, class>
 static char (&test(...))[2];

 static const bool value = sizeof(test<T1, T2>(0)) == 1;

};

B<A> b;

static_assert(!B<A>::value, "Ouch");

This time we might also expect that this should also be well-
formed, relying on the assumption that a function parameter
of type void cannot be valid. But this is a error that happens
"within" A::M<void> and not at the immediate type occurring
in the function declaration

 template<class U1, class U2>
 char test(typename U1::template M<U2>);

> In this case I did not know if the second exception applied because the
> phrase "within the instantiation of a class template" could or could not
> apply to the top level matching of template parameters. If I have:
>
> template <class X> struct Y { };
>
> and the instantiation of the template with:
>
> Y<someType,someOtherType> z;
>
> one could or could not interpret the "within instantiation of the class
> template" as including the matching of template parameters.
> > FCD 14.8.2/7+8:

The point is that the involved type shows up directly in the
function declaration. My loose "top-level" term was supposed to
refer to this immediately occurring type. Another good non-SFINAE
example is this one:

template<typename T>
struct indirect {
 typedef typename T::type type;
};

template<class T>
struct B {
 template<class U>
 static char test(typename indirect<T>::type);

 template<class>
 static char (&test(...))[2];

 static const bool value = sizeof(test<T>(0)) == 1;
};

struct S {
 typedef int type;
};

static_assert(B<S>::value, "Oops"); // OK
static_assert(!B<int>::value, "Oops"); // Error

Again, the error occurs "within" the type indirect<int>,
because type int does not have a member type "type"
and this is not a "top-level" type error.

> > "
> > 7 The substitution occurs in all types and expressions that are used
> > in
> > the function type and in template parameter declarations.[..]
>
> > 8 [..] If a substitution results in an invalid type or expression,
> > type
> > deduction fails. An invalid type or expression is one that would be
> > ill-
> > formed if written using the substituted arguments. [..] Only invalid
> > types
> > and expressions in the immediate context of the function type and its
> > template parameter types can result in a deduction failure. [..]"
>
> I don't know how these passages reflect on the extended SFINAE rules. Is
> a substitution failure as allowed by extended SFINAE exactly the same as
> a type deduction failure as in 14.8.2 paragraph 8 ?

In fact the unofficial SFINAE term is ruled by a deduction failure.

> If that is the case I do not find among the possibiklities an attempt to
> instantiate a class template with the wrong number or wrong type of
> template parameters.

First, the above quoted general statement of 14.8.2/2 can be referred
to in C++03. As I said, this is not 100% clear because the following
individual list does not mention your example.

In C++0x there is no need anymore for an explicit listing. There is
a single-"catch all" phrase quoted above:

"If a substitution results in an invalid type or expression, type
deduction fails. An invalid type or expression is one that would
be ill-formed if written using the substituted arguments."

The further wording only restricts this to non-access situations

"Access checking is not done as part of the substitution process.
Consequently, when deduction succeeds, an access error could
still result when the function is instantiated."

and to types in the "immediate context":

"Only invalid types and expressions in the immediate context
of the function type and its template parameter types can result
in a deduction failure."

HTH & Greetings from Bremen,

Daniel Kr=FCgler


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]



