Проблема при попытке вызвать конструктор копирования в базовом классе, который имеет конструктор std :: any - PullRequest
4 голосов
/ 11 марта 2019

Рассмотрим следующий код:

#include <any>

struct A {
    A();
    A(const A&) = default;
    explicit A(std::any value);
};

struct B: A {
    B() : A() { }
    B(const B& b) : A(b) {}
    explicit B(std::any value) : A(value) {}
};

Компилятор сообщает о следующей ошибке при компиляции (используя clang ++ - 5 или выше):

In file included from <source>:2:
In file included from /opt/compiler-explorer/gcc-7.3.0/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/any:37:
In file included from /opt/compiler-explorer/gcc-7.3.0/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/new:40:
In file included from /opt/compiler-explorer/gcc-7.3.0/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/exception:143:
In file included from /opt/compiler-explorer/gcc-7.3.0/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/bits/nested_exception.h:40:
In file included from /opt/compiler-explorer/gcc-7.3.0/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/bits/move.h:54:
/opt/compiler-explorer/gcc-7.3.0/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/type_traits:149:31: error: no member named 'value' in 'std::is_copy_constructible<B>'
: public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type
                     ~~~~~^
/opt/compiler-explorer/gcc-7.3.0/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/any:192:27: note: in instantiation of template class 'std::__and_<std::is_copy_constructible<B>, std::__not_<std::is_constructible<B, const B &> >, std::__not_<std::__is_in_place_type<B> > >' requested here
          enable_if_t<__and_<is_copy_constructible<_Tp>,
                      ^
/opt/compiler-explorer/gcc-7.3.0/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/any:196:7: note: while substituting prior template arguments into non-type template parameter [with _ValueType = const B &, _Tp = B, _Mgr = std::any::_Manager_external<B>]
  any(_ValueType&& __value)
  ^~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-7.3.0/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/type_traits:973:28: note: while substituting deduced template arguments into function template 'any' [with _ValueType = const B &, _Tp = (no value), _Mgr = (no value), $3 = (no value)]
         = decltype(::new _Tp(declval<_Arg>()))>
                              ^
/opt/compiler-explorer/gcc-7.3.0/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/type_traits:974:24: note: in instantiation of default argument for '__test<B, const B &>' required here
  static true_type __test(int);
                   ^~~~~~~~~~~
/opt/compiler-explorer/gcc-7.3.0/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/type_traits:984:24: note: while substituting deduced template arguments into function template '__test' [with _Tp = B, _Arg = const B &, $2 = (no value)]
  typedef decltype(__test<_Tp, _Arg>(0)) type;
                   ^
/opt/compiler-explorer/gcc-7.3.0/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/type_traits:144:14: note: (skipping 9 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
: public conditional<_B1::value, _B2, _B1>::type
         ^
/opt/compiler-explorer/gcc-7.3.0/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/any:170:17: note: in instantiation of template class 'std::__and_<std::is_copy_constructible<B>, std::is_constructible<B, const B &> >' requested here
  enable_if<__and_<is_copy_constructible<_Tp>,
            ^
/opt/compiler-explorer/gcc-7.3.0/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/any:175:5: note: in instantiation of template type alias '__any_constructible' requested here
using __any_constructible_t =
^
/opt/compiler-explorer/gcc-7.3.0/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.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-7.3.0/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/any:183:7: note: while substituting prior template arguments into non-type template parameter [with _ValueType = const B &, _Tp = B, _Mgr = std::any::_Manager_external<B>]
  any(_ValueType&& __value)
  ^~~~~~~~~~~~~~~~~~~~~~~~~
<source>:63:23: note: while substituting deduced template arguments into function template 'any' [with _ValueType = const B &, _Tp = (no value), _Mgr = (no value), $3 = (no value), $4 = (no value)]
B(const B& b) : A(b) {       
                  ^
1 error generated.
Compiler returned: 1

Интересно, что он компилируется в gcc-7.1 или выше.

Вызывает ли конструктор копирования для B конструктор A вместо конструктора копирования для A, что я и хочу сделать? Если да, то как мне заставить конструктор B-копирования работать так, как я собираюсь это сделать?

p.s. Вот ссылка на онлайн-компилятор, который я использовал для этого https://godbolt.org/z/_22nuW.

...