http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52422

             Bug #: 52422
           Summary: [C++11][SFINAE] Hard errors with void or arithmetic
                    expressions
    Classification: Unclassified
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: daniel.krueg...@googlemail.com


gcc 4.7.0 20120225 (experimental) in C++11 mode produces a hard compiler error
during a sfinae-conforming situation involving function-like or pointer-like
expressions:

//---
template<class T>
struct add_rval_ref
{
  typedef T&& type;
};

template<>
struct add_rval_ref<void>
{
  typedef void type;
};

template<class T>
typename add_rval_ref<T>::type create();

template<class T, 
  class = decltype(create<T>()()) // line 17
>
auto f(int) -> char(&)[1];

template<class>
auto f(...) -> char(&)[2];

static_assert(sizeof(f<void>(0)) != 1, "");
//---

"16|error: void value not ignored as it ought to be"

Here some further variations of the theme:

a) Replace line 17 by

class = decltype(*create<T>()) // line 17

b) Replace above test by

//---
template<class T>
struct add_rval_ref
{
  typedef T&& type;
};

template<>
struct add_rval_ref<void>
{
  typedef void type;
};

template<class T>
typename add_rval_ref<T>::type create();

template<class T, class U,
  class = decltype( (create<T>().*create<U>())() ) // line 17
>
auto f(int) -> char(&)[1];

template<class, class>
auto f(...) -> char(&)[2];

static_assert(sizeof(f<void, void>(0)) != 1, ""); // line 24
//---

"17|error: 'create<void>()' cannot be used as a member pointer, since it is of
type 'add_rval_ref<void>::type {aka void}'"

c) Replace in the test (b) line 24 by the following line:

static_assert(sizeof(f<int, int>(0)) != 1, ""); // line 24

"17|error: 'create<int>()' cannot be used as a member pointer, since it is of
type 'int'"

d) Replace line 17 in the test (b) by the following line and use either of
"void, void" or "int, int" as template arguments in line 24:

class = decltype( create<T>().*create<U>() )

"17|error: 'create<void>()' cannot be used as a member pointer, since it is of
type 'add_rval_ref<void>::type {aka void}'"

or

"17|error: 'create<int>()' cannot be used as a member pointer, since it is of
type 'int'"

respectively.

Reply via email to