template<int N> struct S { typedef int type; }; template<typename T> struct Get { static T get(); }; #ifdef BUG # define ELLIPSIS ... #else # define ELLIPSIS #endif template<typename F> struct B { template<typename ELLIPSIS Args> typename S<sizeof( Get<F>::get() (Get<Args>::get() ELLIPSIS) )>::type f(Args&& ELLIPSIS a); }; struct X { bool operator()(int) const; }; int main() { B<X> b; b.f(1); } jwakely@gcc16:~/src/tests$ g++ -std=c++0x -c pr.cc jwakely@gcc16:~/src/tests$ g++ -std=c++0x -c pr.cc -DBUG pr.cc: In instantiation of ‘B<X>’: pr.cc:35:10: instantiated from here pr.cc:25:9: internal compiler error: in tsubst, at cp/pt.c:9733 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. The code compiles fine with a single template parameter, but not with a parameter pack of size one. I'm trying to use SFINAE to disable overloads when a function call expression is invalid, which is needed to implement std::bind for C++0x
(In reply to comment #0) > I'm trying to use SFINAE to disable overloads when a function call expression > is invalid, which is needed to implement std::bind for C++0x N.B. the use of an invalid expression in a sizeof context is not valid in C++03, but the SFINAE rules were extended to cover general expressions by n2634 so I believe the code is valid in C++0x (see 14.9.2 [temp.deduct] p8 in WP n2914) and should result in a type deduction failure not a hard error.
Jon, are there any hopes for a temporary workaround for std::bind?
The basic problem is I've made std::result_of too good ;-) My new result_of uses decltype to determine the exact result type of an arbitrary function call, including resolving overloads based on whether the callable object and arguments are lvalues or rvalues. If you look at struct _Bind in include/tr1_impl/functional you will see it has multiple overloads of operator() and __call() with different cv-qualifiers. Those overloads are used to ensure the cv qualifiers of the functor _M_f are the same as the cv qualifiers of the _Bind object, as required by [func.bind.bind]. The return type of those overloads uses result_of, but that involves forming invalid expressions e.g. when there is no const volatile operator() on the functor type. I can solve that by using sfinae to remove the overloads when the expression is invalid, but this bug prevents it. A temporary solution would be to remove the const and volatile overloads for now. That will work for 99% of cases, and will pass most of the testsuite, because users don't usually invoke const or volatile binders. This would fail under that workaround: void f(int); auto const b = std::bind(f, 1); b(); Another options would be to support the example above, but to fudge the result_of so that it does not use the correct cv qualifiers. That would fail for this case: struct F { char* operator() const; int operator(); }; i.e. when the cv qualifiers of the function object are significant and affect the result type of the function call operator. For that type, using result_of with the wrong cv qualifiers would cause _Bind to fail, because it infers a result tyep that is not convertible to the actual result of the call.
Subject: Bug 40595 Author: jason Date: Tue Jun 30 19:36:36 2009 New Revision: 149117 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=149117 Log: PR c++/40595 * pt.c (tsubst_pack_expansion): Handle unexpanded packs in an EXPR_PACK_EXPANSION. Added: trunk/gcc/testsuite/g++.dg/cpp0x/variadic94.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/pt.c trunk/gcc/testsuite/ChangeLog
Subject: Bug 40595 Author: jason Date: Tue Jun 30 19:45:21 2009 New Revision: 149118 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=149118 Log: PR c++/40595 * pt.c (tsubst_pack_expansion): Handle unexpanded packs in an EXPR_PACK_EXPANSION. Added: branches/gcc-4_4-branch/gcc/testsuite/g++.dg/cpp0x/variadic94.C - copied unchanged from r149117, trunk/gcc/testsuite/g++.dg/cpp0x/variadic94.C Modified: branches/gcc-4_4-branch/gcc/cp/ChangeLog branches/gcc-4_4-branch/gcc/cp/pt.c branches/gcc-4_4-branch/gcc/testsuite/ChangeLog
Fixed for 4.4.1.
(In reply to comment #6) > Fixed for 4.4.1. This test case causes the same ICE in tsubst also with gcc-4.3.4. After packporting the ICE fix, 4.3.4 instead fails with: variadic94.C: In function 'int main()': variadic94.C:32: sorry, unimplemented: call_expr cannot be mangled due to a defect in the C++ ABI Is this an inherent limitation in 4.3 or just another unfixed bug?
Subject: Re: [C++0x] ICE trying to use sfinae with variadic template pack expansion On 07/01/2009 06:53 AM, mikpe at it dot uu dot se wrote: > Is this an inherent limitation in 4.3 or just another unfixed bug? I'm not planning to fix C++0x bugs in 4.3. Jason