【问题标题】:Difference between passing pointers as function argument vs non type template parameters将指针作为函数参数传递与非类型模板参数之间的区别
【发布时间】:2021-06-10 01:37:52
【问题描述】:

我无法理解两者之间的区别

  1. 将指针作为函数参数传递
  2. 将指针作为非类型模板参数传递

您能否帮助了解通过选择 2 实现了哪些优化(特别是在 here 和使用 here 解释的快速代表的上下文中)?

我对使用指针作为非类型参数的一些困惑是

  1. 在编译时解析指针时,编译器如何知道指针指向的内容?
  2. 当成员函数可以是虚函数时,如何在编译时解析成员函数指针?

【问题讨论】:

    标签: c++ c++17 signals-slots member-function-pointers non-type-template-parameter


    【解决方案1】:

    在编译时解析指针时,编译器如何知道指针指向的内容?

    因为这就是模板的工作方式。尽管模板很复杂,但其基本思想却非常简单。

    模板是一个(智能)宏。实例化模板时,基本上是在创建模板的副本,其中模板参数的每次使用都被实例化时传递的相应参数替换。

    所以这个:

    template<func_ptr ptr>
    void func1();
    {
      ptr();
    }
    
    func1<some_func>();
    

    在功能上等同于:

    void func2()
    {
      some_func();
    }
    
    func2();
    

    编译器如何知道func2 将调用some_func?因为这就是你在代码中写的字面意思。编译器怎么知道func1&lt;some_func&gt; 会调用some_func?因为当您将其命名为 func1&lt;some_func&gt; 时,这就是您在代码中所写的内容

    当成员函数可以是虚函数时,如何在编译时解析成员函数指针?

    这一切都取决于您所说的“已解决”。

    假设函数调用成员指针的类不是final(你不能从final类继承,所以编译器确切地知道要调用哪个函数),编译器无法确定到底是哪个将调用 override。

    但是,编译器确实知道覆盖在哪里。假设我们正在讨论基于 vtable 的虚函数实现,则成员指针包含指向 vtable 的索引,编译器将使用该索引来查找实际的覆盖函数。但是如果成员指针在编译时已知,则意味着索引在编译时是已知的。所以编译器不需要动态索引到表中;它可以对其进行静态索引。

    所以在某种程度上,它可以被认为在编译时已经“解决”了覆盖。至少,在可能的范围内。

    【讨论】:

    • 感谢您的回复。我做了更多研究,发现以下en.cppreference.com/w/cpp/language/template_parameters 模板参数对象应具有不断破坏。 stackoverflow.com/questions/5687540/… 传入其指针的变量必须有外部链接。那么函数指针在每个作用域中也都有外部链接吗?
    • @Discretizer:函数不是对象,所以函数指针不指向变量。
    • 在您的函数示例中,将函数指针作为参数传递与模板参数之间有区别吗?除非函数以某种方式内联,否则似乎没有优化。
    • @Discretizer:自 C++17 以来,链接不再是模板参数要求。
    • @Discretizer:创建一个局部变量 static 不会给它链接,但它确实给它静态存储持续时间必填。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-24
    • 1970-01-01
    • 2013-03-30
    • 1970-01-01
    相关资源
    最近更新 更多