【问题标题】:Can someone help me enlighten this template?有人可以帮我启发这个模板吗?
【发布时间】:2020-04-15 17:17:53
【问题描述】:

我知道标题很烂,只是我真的不知道该怎么问这个问题,因为我缺乏许多基本 C++ 功能的知识,我正在尝试一一解决。

所以我开始深入研究 C++ 模板。现在我正在构建非常基本的,只是为了帮助我调试我的代码,比如:

    void printVectors(const T& vec, const S& vec2) {
        for (int i = 0; i < vec.size(); i++) {
            print("------------");
            printNoEndln(vec[i]);
            printNoEndln("->");
            print(vec2[i]);
        }
    }

现在,从 SDL 开始,我遇到了这样的事情:

    template <typename T, typename... TArgs>
    T& AddComponent(TArgs&&... args) {
        T* newComponent(new T(std::forward<TArgs>(args)...));
        newComponent->componentName = typeid(T).name();
        newComponent->owner = this;
        components.emplace_back(newComponent);
        newComponent->Init();
        return *newComponent;
    }

所以我将逐行描述我的理解,如果你们能纠正我,我会很高兴。

1- 创建一个带有 N 个参数的 T 类型模板(这就是扩展运算符在这里的意思,对吗?它声明了一个可变参数模板?)

2- 声明一个函数AddComponent,它返回 T 的引用并接收 TArgs (???) 类型的引用的 N 个引用(这部分让我很困惑)。

3- 以一种非常奇怪的方式声明指向 T 类型的新对象的指针 T。对于初学者,我不明白为什么newComponent 的实例化是用() 来解决的,例如newComponent() 而不是T* newComponent = new Component(...)(说真的,这就是我从这条线所能掌握的全部)

从第 4 行开始,代码对我来说非常简单,不需要任何解释。

据我所知,我的差距在于无法理解:可变参数模板和函数、右值、左值和前向问题。那是对的吗?你们能指点我关于这些主题的有用文章吗?我发现大多数 cpp 参考非常正式,远远超出了我的范围。有趣的是,我可以毫无问题地阅读 C#、Java、Typescript 和 Javascript 文档,但是当涉及到 C++ 时,很难从文档中提取一些东西。我通常只是跳过形式到实际的示例代码,然后我自己在编译器上进行尝试以了解发生了什么。

我知道这很多,请回答您认为有用的任何信息。

谢谢大家

【问题讨论】:

标签: c++ templates variadic-templates


【解决方案1】:
template <typename T, typename... TArgs>
T& AddComponent(TArgs&&... args)

这是函数模板AddComponent 的声明。 TTArgs 是模板参数,两者都必须是类型。 TArgs 是一个可变参数(可以容纳 0 个或多个类型)。 function templateTTArgs 的每个独特组合删除函数,例如。 AddComponent&lt;int,long,float&gt; 可以是这样的功能。

TArgs&amp;&amp;... 被称为forwarding references,因为模板声明中的&amp;&amp; 具有保留参数的值类别(左值/右值)的效果。

    T* newComponent(new T(std::forward<TArgs>(args)...));

这是一个局部变量newComponent的定义,类型为指向T和初始值new T(std::forward&lt;TArgs&gt;(args)...)

std::forward 是一个辅助实用程序,可与TArgs&amp;&amp; 一起使用,并在需要时将右值引用传递给调用。浏览代码时可以忽略它,将new T(std::forward&lt;TArgs&gt;(args)...) 读作new T(args...)。现在这是一个可变参数pack expansion 语法;这里模板中的参数args 被简单地传递给new()

欲了解更多详情,请参阅您最喜欢的C++ Book。我最喜欢(几年前)是 Scott Meyers 的Effective Modern C++(Scott 称转发参考通用参考,其余的都是一本好书)。

【讨论】:

  • 非常感谢您抽出宝贵的时间!现在一切都非常清楚了!我仍然无法理解与指向 T 的指针关联的局部变量的这个声明。为什么我们要“调用”newComponent 来定义它的初始值?这种语法是否只发生在模板内?我无法在模板范围之外真正重现它。
  • 这是直接初始化,C++ 中最古老的语法。 int i(5); 是另一个例子。不建议这样做,因为它会导致臭名昭著的最令人烦恼的解析。现代 C++ 替代语法是 int i{5};
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-13
  • 2015-05-31
  • 2020-03-25
  • 2016-07-09
相关资源
最近更新 更多