Введите trait на std :: reference_wrapper - PullRequest
0 голосов
/ 28 февраля 2019

std::reference_wrapper должен быть копируемым, независимо от типа содержимого (это просто указатель внутри).Однако при утверждении, что использование

static_assert(std::is_copy_constructible<std::reference_wrapper<std::any> >::value, "!");

Clang завершает работу с ошибкой компиляции из STL, в то время как GCC сообщает об отсутствии проблем.Это не относится к другим типам (я тестировал std::reference_wrapper<int> и std::any напрямую).

У меня есть пример, показывающий компиляцию в GCC и Clang на https://godbolt.org/z/7YwkWb.

.Я понимаю, что даже если тип, заданный для std::is_copy_constructible, не является копируемым, он должен просто давать ложное время компиляции, а не сбой компиляции.В чем здесь проблема?Это ошибка компилятора или я что-то упустил?

Ошибка компиляции из Clang:

In file included from <source>:1:
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/type_traits:132:31: error: no member named 'value' in 'std::is_copy_constructible<std::reference_wrapper<std::any> >'
    : public conditional<_B1::value, _B2, _B1>::type
                         ~~~~~^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/any:170:17: note: in instantiation of template class 'std::__and_<std::is_copy_constructible<std::reference_wrapper<std::any> >, std::is_constructible<std::reference_wrapper<std::any>, const std::reference_wrapper<std::any> &> >' requested here
      enable_if<__and_<is_copy_constructible<_Tp>,
                ^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/any:175:5: note: in instantiation of template type alias '__any_constructible' requested here
    using __any_constructible_t =
    ^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/any:181:56: note: in instantiation of template type alias '__any_constructible_t' requested here
              __any_constructible_t<_Tp, _ValueType&&> = true,
                                                       ^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/any:183:7: note: while substituting prior template arguments into non-type template parameter [with _ValueType = const std::reference_wrapper<std::any> &, _Tp = std::reference_wrapper<std::any>, _Mgr = std::any::_Manager_internal<std::reference_wrapper<std::any> >]
      any(_ValueType&& __value)
      ^~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/type_traits:921:56: note: while substituting deduced template arguments into function template 'any' [with _ValueType = const std::reference_wrapper<std::any> &, _Tp = (no value), _Mgr = (no value), $3 = (no value), $4 = (no value)]
      : public __bool_constant<__is_constructible(_Tp, _Args...)>
                                                       ^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/type_traits:933:14: note: in instantiation of template class 'std::is_constructible<std::reference_wrapper<std::any>, const std::reference_wrapper<std::any> &>' requested here
    : public is_constructible<_Tp, const _Tp&>
             ^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/type_traits:939:14: note: in instantiation of template class 'std::__is_copy_constructible_impl<std::reference_wrapper<std::any>, true>' requested here
    : public __is_copy_constructible_impl<_Tp>
             ^
<source>:12:20: note: in instantiation of template class 'std::is_copy_constructible<std::reference_wrapper<std::any> >' requested here
static_assert(std::is_copy_constructible<std::reference_wrapper<std::any> >::value, "!");
                   ^
In file included from <source>:1:
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/type_traits:137:31: error: no member named 'value' in 'std::is_copy_constructible<std::reference_wrapper<std::any> >'
    : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type
                         ~~~~~^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/any:192:27: note: in instantiation of template class 'std::__and_<std::is_copy_constructible<std::reference_wrapper<std::any> >, std::__not_<std::is_constructible<std::reference_wrapper<std::any>, const std::reference_wrapper<std::any> &> >, std::__not_<std::__is_in_place_type<std::reference_wrapper<std::any> > > >' requested here
              enable_if_t<__and_<is_copy_constructible<_Tp>,
                          ^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/any:196:7: note: while substituting prior template arguments into non-type template parameter [with _ValueType = const std::reference_wrapper<std::any> &, _Tp = std::reference_wrapper<std::any>, _Mgr = std::any::_Manager_internal<std::reference_wrapper<std::any> >]
      any(_ValueType&& __value)
      ^~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/type_traits:921:56: note: while substituting deduced template arguments into function template 'any' [with _ValueType = const std::reference_wrapper<std::any> &, _Tp = (no value), _Mgr = (no value), $3 = (no value)]
      : public __bool_constant<__is_constructible(_Tp, _Args...)>
                                                       ^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/type_traits:933:14: note: in instantiation of template class 'std::is_constructible<std::reference_wrapper<std::any>, const std::reference_wrapper<std::any> &>' requested here
    : public is_constructible<_Tp, const _Tp&>
             ^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/type_traits:939:14: note: in instantiation of template class 'std::__is_copy_constructible_impl<std::reference_wrapper<std::any>, true>' requested here
    : public __is_copy_constructible_impl<_Tp>
             ^
<source>:12:20: note: in instantiation of template class 'std::is_copy_constructible<std::reference_wrapper<std::any> >' requested here
static_assert(std::is_copy_constructible<std::reference_wrapper<std::any> >::value, "!");
                   ^
2 errors generated.
Compiler returned: 1

1 Ответ

0 голосов
/ 28 февраля 2019

Вверху ясно видна ошибка, что std::is_copy_constructible не имеет члена value для проверяемой вами специализации.Теперь типы, которые вы передаете, не нарушают контракт std::is_copy_constructible, поэтому нет риска неопределенного поведения.

Это означает только одно, это не проблема компилятора, а проблема реализации стандартной библиотеки.Clang использует стандартную реализацию стандартной библиотеки, установленную по умолчанию, которая в системе godbolt имеет значение libstdc++ (реализация GNU).Это, очевидно, вызывает проблему из-за некоторой возможной мягкой несовместимости.

Если вы указали опцию -stdlib=libc++ (libc++ - это реализация стандартной библиотеки LLVM) при сборке с Clang, то он прекрасно принимает код.

...