lundi 3 juin 2019

Why does this SFINAE give an error in gcc?

Consider the following example (https://godbolt.org/z/pSTUZI):

#include <iterator>
#include <type_traits>

template <typename T>
struct falsy : std::false_type {};

template <
  typename T,
  typename std::enable_if<falsy<T>::value, int>::type = 0>
void f(std::back_insert_iterator<T>) {}

template <typename T>
void f(T) {}

struct S {};

int main() {
  S s;
  f<S>(s);
}

Compiling it with gcc 8.3 or earlier gives an error:

In file included from /opt/compiler-explorer/gcc-8.3.0/include/c++/8.3.0/iterator:63,

                 from <source>:1:

/opt/compiler-explorer/gcc-8.3.0/include/c++/8.3.0/bits/stl_iterator.h: In instantiation of 'class std::back_insert_iterator<S>':

<source>:19:9:   recursively required by substitution of 'template<class T, typename std::enable_if<falsy<T>::value, int>::type <anonymous> > void f(std::back_insert_iterator<_Container>) [with T = S; typename std::enable_if<falsy<T>::value, int>::type <anonymous> = <missing>]'

<source>:19:9:   required from here

/opt/compiler-explorer/gcc-8.3.0/include/c++/8.3.0/bits/stl_iterator.h:490:7: error: no type named 'value_type' in 'struct S'

       operator=(const typename _Container::value_type& __value)

       ^~~~~~~~

/opt/compiler-explorer/gcc-8.3.0/include/c++/8.3.0/bits/stl_iterator.h:497:7: error: no type named 'value_type' in 'struct S'

       operator=(typename _Container::value_type&& __value)

       ^~~~~~~~

while clang and gcc 9 compile it without any errors. Is this example a correct use of SFINAE and is it a bug in gcc < 9?

Aucun commentaire:

Enregistrer un commentaire