c++ std::apply emplace_back with a parameter pack

pdkcd3nj  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(122)

我试图将一个新对象放置到模板函数中的容器中。由于模板函数接收到一个std::tuple,其中包含创建对象所需的参数,因此我使用std::apply和fold表达式来解包元组值。然而,它无法编译
我的代码相当于

  1. #include <vector>
  2. struct S
  3. {
  4. S(float restAngle, bool useIt)
  5. : restAngle(restAngle)
  6. , useIt(useIt)
  7. {}
  8. float restAngle;
  9. bool useIt;
  10. };
  11. int main()
  12. {
  13. std::tuple t(0.0F, false);
  14. std::vector<S> ss;
  15. std::apply([&ss](auto ...data) {ss.emplace_back((data,...));}, t);
  16. }

字符串
在gcc 13中出现以下编译错误,

  1. n file included from /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/x86_64-linux-gnu/bits/c++allocator.h:33,
  2. from /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/allocator.h:46,
  3. from /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/vector:63,
  4. from <source>:1:
  5. /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/new_allocator.h: In instantiation of 'void std::__new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = S; _Args = {bool&}; _Tp = S]':
  6. /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/alloc_traits.h:537:17: required from 'static void std::allocator_traits<std::allocator<_Tp1> >::construct(allocator_type&, _Up*, _Args&& ...) [with _Up = S; _Args = {bool&}; _Tp = S; allocator_type = std::allocator<S>]'
  7. /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/vector.tcc:117:30: required from 'std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {bool&}; _Tp = S; _Alloc = std::allocator<S>; reference = S&]'
  8. <source>:18:52: required from 'main()::<lambda(auto:1 ...)> [with auto:1 = {float, bool}]'
  9. /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/type_traits:2558:26: required by substitution of 'template<class _Fn, class ... _Args> static std::__result_of_success<decltype (declval<_Fn>()((declval<_Args>)()...)), std::__invoke_other> std::__result_of_other_impl::_S_test(int) [with _Fn = main()::<lambda(auto:1 ...)>; _Args = {float&, bool&}]'
  10. /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/type_traits:2569:55: [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
  11. /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/type_traits:161:35: recursively required by substitution of 'template<class _Result, class _Ret> struct std::__is_invocable_impl<_Result, _Ret, true, std::__void_t<typename _CTp::type> > [with _Result = std::__invoke_result<main()::<lambda(auto:1 ...)>, float&, bool&>; _Ret = void]'
  12. /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/type_traits:161:35: required by substitution of 'template<class ... _Bn> std::__detail::__first_t<std::integral_constant<bool, true>, typename std::enable_if<(bool)(_Bn::value), void>::type ...> std::__detail::__and_fn(int) [with _Bn = {std::__is_invocable_impl<std::__invoke_result<main()::<lambda(auto:1 ...)>, float&, bool&>, void, true, void>, std::__call_is_nothrow<std::__invoke_result<main()::<lambda(auto:1 ...)>, float&, bool&>, main()::<lambda(auto:1 ...)>, float&, bool&>}]'
  13. /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/type_traits:177:42: required from 'struct std::__and_<std::__is_invocable_impl<std::__invoke_result<main()::<lambda(auto:1 ...)>, float&, bool&>, void, true, void>, std::__call_is_nothrow<std::__invoke_result<main()::<lambda(auto:1 ...)>, float&, bool&>, main()::<lambda(auto:1 ...)>, float&, bool&> >'
  14. /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/type_traits:3103:12: required from 'struct std::is_nothrow_invocable<main()::<lambda(auto:1 ...)>, float&, bool&>'
  15. /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/tuple:2272:31: required from 'constexpr const bool std::__unpack_std_tuple<template<class _Fn, class ... _ArgTypes> struct std::is_nothrow_invocable, main()::<lambda(auto:1 ...)>, std::tuple<float, bool>&>'
  16. /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/tuple:2295:14: required from 'constexpr decltype(auto) std::apply(_Fn&&, _Tuple&&) [with _Fn = main()::<lambda(auto:1 ...)>; _Tuple = tuple<float, bool>&]'
  17. <source>:18:15: required from here
  18. /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/new_allocator.h:187:11: error: no matching function for call to 'S::S(bool&)'
  19. 187 | { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
  20. | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  21. <source>:5:5: note: candidate: 'S::S(float, bool)'
  22. 5 | S(float restAngle, bool useIt)
  23. | ^
  24. <source>:5:5: note: candidate expects 2 arguments, 1 provided
  25. <source>:3:8: note: candidate: 'constexpr S::S(const S&)'
  26. 3 | struct S
  27. | ^
  28. <source>:3:8: note: no known conversion for argument 1 from 'bool' to 'const S&'
  29. <source>:3:8: note: candidate: 'constexpr S::S(S&&)'
  30. <source>:3:8: note: no known conversion for argument 1 from 'bool' to 'S&&'


我找不到代码的错误。显然是试图只使用bool参数调用emplace_back,我不明白。代码有什么问题?

py49o6xq

py49o6xq1#

你的语法有点不对。

  1. ss.emplace_back((data,...))

字符串
您正在data包上使用逗号运算符的折叠表达式,因此它扩展为

  1. ss.emplace_back((data1, data2, ..., dataN))


因为它是逗号操作符,所以只有dataN从内括号中返回,在本例中,内括号是元组的bool对象。

  1. ss.emplace_back(data...)


扩张至

  1. ss.emplace_back(data1, data2, ..., dataN)


这就是对emplace_back的调用的样子。

展开查看全部

相关问题