用于通用和快速数据存储容器构建器的 C++ 可变参数模板

C++ Variadic Templates for a General-Purpose and Fast Data Storage Container Builder

提问人:zahid kamil 提问时间:1/17/2022 最后编辑:Enlicozahid kamil 更新时间:10/9/2022 访问量:117

问:

template< typename ... Args>
auto build_array(Args&&... args) -> std::array<typename std::common_
type<Args...>::type, sizeof...(args)>
{
    using commonType = typename std::common_type<Args...>::type;
    return {std::forward<commonType>(args)...};
}

int main()
{
    auto data = build_array(1, 0u, 'a', 3.2f, false);
    for(auto i: data)
    std::cout << i << " ";
    std::cout << std::endl;
}

嘿,伙计们,我无法理解上面的代码。所以基本上,代码是编写一个函数,该函数接受任意数量的任何类型的元素,而这些元素又可以转换为通用类型。该函数还应该返回一个容器,该容器将所有元素转换为该通用类型,并且它也应该可以快速遍历。这是一个书籍解决方案。

据我了解,允许参数的变化。那么,还允许各种参数,但只允许重值?我不明白箭头表示法和函数声明的其余部分。就像它们之间有什么区别。此外,这本书还传入了?对于模板,例如?<typename... Args>(Args&&...args)std::array<?,?>

最后,return 语句到底是什么意思(以省略号结尾?并向前? 对不起,我正在漫无边际,但我就是无法理解并详细了解正在发生的事情。 如果你能详细说明这一点,那你真的很善良吗?

C++ 14 C+ +-标准库

评论

0赞 user12002570 1/17/2022
箭头表示法称为尾随返回类型。例如请参阅此处和此处。因此,函数的返回类型为std::array<typename std::common_ type<Args...>::type, sizeof...(args)>
0赞 康桓瑋 1/17/2022
Args&&是可以绑定左值或右值的转发引用

答:

2赞 Enlico 1/17/2022 #1

但只有 rvalues?

当你看到 ,T&&

  • 如果不是模板参数,则表示对 的右值引用,它只能绑定到 rvalules;TT&&T
  • if 是模板参数,则表示对 的转发/通用引用,它可以绑定到右值和左值。TT&&T

因此,在您的情况下,由于是一个模板参数包(确切地说是类型模板参数包此处的数字 (2)),扩展为逗号分隔的函数参数声明序列,每个声明都有类型转发引用。例如,如果将 3 个参数传递给 ,则推导就像您有这样的声明一样:ArgsArgs&&... argsbuild_array

template<typename Arg1, typname Arg2, typname Arg3>
auto build_array(Arg1&& arg1, Arg2&& arg2, Arg3&& arg3)
    -> std::array<typename std::common_type<Arg1, Arg2, Arg3>::type, 3>

return 语句甚至是什么意思(以省略号结尾?

同样,是在逗号分隔的事物序列中扩展一些可变的东西。所以如果在...args

return {std::forward<commonType>(args)...};

实际上是 3 件事,那么该语句扩展为

return {std::forward<commonType>(arg1), std::forward<commonType>(arg2), std::forward<commonType>(arg3)};

注意省略号的位置。 扩展为 ,而将扩展为 。f(args)...f(arg1), f(arg2), f(arg3), …f(args...)f(arg1, arg2, arg3, …)

并向前?

这可能是不太容易理解的一点,需要一个专门的问题。然而,关于这个主题的问题已经存在很多,所以你只需要搜索它们,而不是问一个新的问题。这是我的一个答案,我最清楚地解释了 和 之间的区别。如果你把理解我的答案作为你的目标,你就会理解(和),一切都会更清楚。std::movestd::forwardstd::forwardstd::move

我不明白箭头表示法和函数声明的其余部分。

本质上

auto f(/* parameters */) -> SomeType

相当于

SomeType f(/* parameters */)

优点是,如果需要,前者可以引用 中的类型。在本例中,返回类型使用 。SomeType/* parameters */Args

本书还传入了模板,例如??std::array<?,?>

可能这本书只是试图引导你完成论证演绎,它的意思是“我们还不知道它是什么;继续阅读”。?