1

我意识到嵌套的 std::any 是个坏主意。尽管如此,我遇到了一些让我摸不着头脑的事情,我只是想了解编译器为什么会窒息。考虑以下代码行(假设arg变量是包含另一个 std::any 的 std::any):

auto result = std::any_cast<std::any>(arg);

那行编译得很好。现在,考虑这一行,其中我有一个 std::any 包含一个 std::tuple 包含另一个 std::any:

auto result = std::any_cast<std::tuple<std::any>>(arg);

现在,编译器崩溃了。这些是我得到的错误:

In file included from /home/james/git/trogdor-pp/src/core/event/triggers/luaeventtrigger.cpp:1:
In file included from /home/james/git/trogdor-pp/src/core/include/trogdor/game.h:5:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:37:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/new:40:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/exception:144:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/nested_exception.h:40:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/move.h:55:
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:132:31: error: no member named 'value' in 'std::is_copy_constructible<std::tuple<std::any> >'
    : public conditional<_B1::value, _B2, _B1>::type
                         ~~~~~^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:170:17: note: in instantiation of template class 'std::__and_<std::is_copy_constructible<std::tuple<std::any> >, std::is_constructible<std::tuple<std::any>, const std::tuple<std::any> &> >' requested here
      enable_if<__and_<is_copy_constructible<_Tp>,
                ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:175:5: note: in instantiation of template type alias '__any_constructible' requested here
    using __any_constructible_t =
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:181:56: note: in instantiation of template type alias '__any_constructible_t' requested here
              __any_constructible_t<_Tp, _ValueType&&> = true,
                                                       ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:183:7: note: while substituting prior template arguments into non-type template parameter [with _ValueType = const std::tuple<std::any> &, _Tp = std::tuple<std::any>, _Mgr = std::any::_Manager_external<std::tuple<std::any> >]
      any(_ValueType&& __value)
      ^~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:884:56: note: while substituting deduced template arguments into function template 'any' [with _ValueType = const std::tuple<std::any> &, _Tp = (no value), _Mgr = (no value), $3 = (no value), $4 = (no value)]
      : public __bool_constant<__is_constructible(_Tp, _Args...)>
                                                       ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:884:32: note: (skipping 2 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
      : public __bool_constant<__is_constructible(_Tp, _Args...)>
                               ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:908:14: note: in instantiation of template class 'std::__is_copy_constructible_impl<std::tuple<std::any>, true>' requested here
    : public __is_copy_constructible_impl<_Tp>
             ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:109:14: note: in instantiation of template class 'std::is_copy_constructible<std::tuple<std::any> >' requested here
    : public conditional<_B1::value, _B1, _B2>::type
             ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:358:16: note: in instantiation of template class 'std::__or_<std::is_reference<std::tuple<std::any> >, std::is_copy_constructible<std::tuple<std::any> > >' requested here
      { return __or_<is_reference<_Tp>, is_copy_constructible<_Tp>>::value; }
               ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:481:26: note: in instantiation of function template specialization 'std::any::__is_valid_cast<std::tuple<std::any> >' requested here
      static_assert(any::__is_valid_cast<_ValueType>(),
                         ^
/home/james/git/trogdor-pp/src/core/event/triggers/luaeventtrigger.cpp:42:32: note: in instantiation of function template specialization 'std::any_cast<std::tuple<std::any> >' requested here
               auto arg = std::any_cast<std::tuple<std::any>>(a);
                               ^
In file included from /home/james/git/trogdor-pp/src/core/event/triggers/luaeventtrigger.cpp:1:
In file included from /home/james/git/trogdor-pp/src/core/include/trogdor/game.h:5:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:37:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/new:40:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/exception:144:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/nested_exception.h:40:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/move.h:55:
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:137:31: error: no member named 'value' in 'std::is_copy_constructible<std::tuple<std::any> >'
    : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type
                         ~~~~~^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:150:37: note: in instantiation of template class 'std::__and_<std::is_copy_constructible<std::tuple<std::any> >, std::__not_<std::is_constructible<std::tuple<std::any>, const std::tuple<std::any> &> >, std::__not_<std::__is_in_place_type<std::tuple<std::any> > > >' requested here
    inline constexpr bool __and_v = __and_<_Bn...>::value;
                                    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:192:27: note: in instantiation of variable template specialization 'std::__and_v<std::is_copy_constructible<std::tuple<std::any> >, std::__not_<std::is_constructible<std::tuple<std::any>, const std::tuple<std::any> &> >, std::__not_<std::__is_in_place_type<std::tuple<std::any> > > >' requested here
              enable_if_t<__and_v<is_copy_constructible<_Tp>,
                          ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:196:7: note: while substituting prior template arguments into non-type template parameter [with _ValueType = const std::tuple<std::any> &, _Tp = std::tuple<std::any>, _Mgr = std::any::_Manager_external<std::tuple<std::any> >]
      any(_ValueType&& __value)
      ^~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:884:56: note: while substituting deduced template arguments into function template 'any' [with _ValueType = const std::tuple<std::any> &, _Tp = (no value), _Mgr = (no value), $3 = (no value)]
      : public __bool_constant<__is_constructible(_Tp, _Args...)>
                                                       ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:884:32: note: while substituting deduced template arguments into function template 'tuple' [with _Dummy = (no value), $1 = (no value)]
      : public __bool_constant<__is_constructible(_Tp, _Args...)>
                               ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:902:14: note: (skipping 1 context in backtrace; use -ftemplate-backtrace-limit=0 to see all)
    : public is_constructible<_Tp, const _Tp&>
             ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:908:14: note: in instantiation of template class 'std::__is_copy_constructible_impl<std::tuple<std::any>, true>' requested here
    : public __is_copy_constructible_impl<_Tp>
             ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:109:14: note: in instantiation of template class 'std::is_copy_constructible<std::tuple<std::any> >' requested here
    : public conditional<_B1::value, _B1, _B2>::type
             ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:358:16: note: in instantiation of template class 'std::__or_<std::is_reference<std::tuple<std::any> >, std::is_copy_constructible<std::tuple<std::any> > >' requested here
      { return __or_<is_reference<_Tp>, is_copy_constructible<_Tp>>::value; }
               ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:481:26: note: in instantiation of function template specialization 'std::any::__is_valid_cast<std::tuple<std::any> >' requested here
      static_assert(any::__is_valid_cast<_ValueType>(),
                         ^
/home/james/git/trogdor-pp/src/core/event/triggers/luaeventtrigger.cpp:42:32: note: in instantiation of function template specialization 'std::any_cast<std::tuple<std::any> >' requested here
               auto arg = std::any_cast<std::tuple<std::any>>(a);

我很难解开所有这些并找出问题所在以及如何解决它。

编辑:我们在评论中发现此代码不能在 G++ 9 及更低版本下编译,但在 G++ 10 及更高版本上编译,并且在 clang 10 及更低版本上也失败,但在 clang 11 及更高版本上编译。有没有人猜测为什么会这样?

4

1 回答 1

2

关键部分是错误:no member named 'value' in 'std::is_copy_constructible<std::tuple<std::any> >'

这是编译器抱怨指示对象 thestd::tuple不可复制构造的方式。

显然,您的 gcc 不相信 std::tupestd::any 是可复制构造的。如果元组中的所有内容都是可复制构造的,则元组本身应该是可复制构造的。鉴于那std::any是 C++17,而 gcc 9 的 C++17 支持是不完整的,至少就 C++17 的这一部分而言是不完整的(gcc 11 的功能列表仍然包括一些 C++17 功能)。

于 2020-12-06T04:15:05.920 回答