gpt4 book ai didi

c++ - C++中是否存在真正的静态多态性?

转载 作者:IT老高 更新时间:2023-10-28 21:41:28 26 4
gpt4 key购买 nike

这是C++中的简单代码:

#include <iostream>
#include <typeinfo>

template<typename T>
void function()
{
std::cout << typeid(T).name() << std::endl;
}

int main()
{
function<int>();
function<double>();
return 0;
}

我已经读过C++中的模板是一种编译时功能,这与C#/Java中的泛型不一样。

因此,据我所知,C++编译器会将单个定义的函数划分为各种函数(取决于具有不同类型的调用数)。

我说的对吗?我不是C++编译器专家,所以我想向您提出一些建议。

如果我对编译器输出的建议是正确的,我想知道是否可以将上面的代码描述为静态多态性?

因为它似乎没有被覆盖,而只是从可执行文件中调用一个副本,或者...应用程序在输出二进制图像中具有什么都没有关系,但是只有重要的部分在C++代码级别中,我不关注编译器如何产生输出。

最佳答案

Is there real static polymorhism in C++?



绝对-静态多态有三种机制:模板,宏和函数重载。

So as I understood, the C++ compiler will divide a single defined function into various number (depends on calls count with different type) of functions. Am I right or not?



那是一般的想法。实例化的函数数量取决于模板参数的排列数量,可以在 function<int>function<double>中明确指定,或者-对于使用模板参数匹配函数参数的模板-例如,自动从函数参数派生:
template <typename T, size_t N>
void f(T (&array)[N])
{ }

double d[2];
f(d); // instantiates/uses f<double, 2>()

您最终应该在可执行二进制镜像中得到每个实例化模板的单个副本。

I want to know if I can describe the code above as static polymorphism?



不是。
  • template<> function实例化为两种类型
  • 至关重要的是,多态性是,而不是用于选择要分配给调用站点
  • function的两个实例中的哪一个。
  • 琐碎地在此类实例化期间对typeid(T)int评估了double,并且从程序员的角度有效地多态地表现的行为(尽管它是编译器关键字-实现未知)
  • 琐碎地混合了静态和名义上的动态(但这里可能是静态的)多态性,支持您使用std::cout

  • 背景-多态性和代码生成

    我认为对多态性至关重要的要求是:
  • 在编译代码时(无论是“常规”代码还是每个模板实例化或宏替换),编译器都会自动选择(如果需要,创建)-内联或调用-不同的类型适当的行为(机器代码)
  • ,即代码选择/创建仅由编译器根据所涉及变量的类型完成,而不是由程序员在不同的函数名称/实例之间进行选择而明确地硬编码,每个函数名称/实例仅能够处理一种类型或
  • 类型的排列
    例如
  • ,随着std::cout << x;类型的变化,x多态调用不同的代码,但仍输出x的值,而非多态printf("%d", x)处理int s,但如果printf("%c", x);成为x,则需要手动将其修改为char

  • 但是,我们要通过多态性实现的目标更加笼统:
  • 对多种类型的数据重用算法代码,而无需嵌入显式的类型检测和分支代码
  • ,即程序源代码不包含if (type == X) f1(x) else f2(x);-样式代码
  • 减少了维护负担,因为在显式更改变量的类型后,需要在整个源代码
  • 中手动进行较少的后续更改

    C++支持这些较大的方面,如下所示:

  • 实例化
  • 相同的源代码来为某些其他类型的或类型的排列(这是参数多态性)生成不同的行为(机器代码)
  • 实际上被称为“实例化”(用于模板)和“替代”(用于预处理器宏),但为方便起见,以下我将使用“实例化”;从概念上讲,是重新编译或重新解释...
  • 隐式将(静态或动态)分派(dispatch)给独特行为(机器代码),它适合于正在处理的数据的独特类型

  • ...并且按照我在 Polymorphism in c++上的回答以一些较小的方式

    不同类型的多态性涉及其中一个或两个:
  • 调度(1)对于模板和预处理器
  • (2)可以在实例化(1)的过程中发生
  • 实例化(1)通常在调度(2)期间针对模板(无匹配的完全特化)和类似函数的(有点周期性,尽管宏不会递归扩展)
  • 调度(2)可以在没有的实例化(1)的情况下发生,而不是(1),当编译器选择预先存在的函数重载模板专用化/或编译器触发虚拟机时。

  • 您的代码实际使用什么?
    function<int>function<double>重用function模板代码来为每种类型的代码创建不同的代码,因此您将如上所述获得实例化(1)。但是,您正在硬编码要调用的实例化,而不是让编译器根据某些参数的类型隐式选择实例化,即因此在调用function时您不直接利用隐式调度ala(2)。实际上,function缺少编译器可用于隐式选择模板实例化的参数。

    仅实例化(1)不够,不足以使不足以考虑您的代码已使用多态性。仍然,您已经实现了方便的代码重用

    那么什么将是明确多态的呢?

    为了说明模板如何支持调度(2)和实例化(1)并毫无疑问地提供“多态性”,请考虑:
    template<typename T>
    void function(T t)
    {
    std::cout << typeid(T).name() << std::endl;
    }

    function(4); // note: int argument, use function<int>(...)
    function(12.3); // note: double argument, use function<double>(...)

    上面的代码还利用隐式调度来分配类型合适的代码-方面“2”。以上-多态性。

    非类型参数

    有趣的是,C++提供了使用 bool 值,int和指针常量之类的完整参数实例化模板的功能,并将它们用于所有事情,而无需更改数据类型,因此不涉及任何多态性。宏更加灵活。

    请注意,在C.R.T.P.样式不是静态多态性的要求-这是其示例应用程序。在实例化期间,将操作与参数指定类型的实现进行匹配时,编译器会表现出静态多态性。

    术语讨论

    很难确定多态性的确切定义。维基百科引用Bjarne Stroustrup的在线词汇表“为不同类型的实体提供单个接口(interface)”:这意味着struct X { void f(); }; struct Y { void f(); };已经表现出多态性,但是恕我直言,当我们使用来自客户端代码的接口(interface)对应关系时,我们只能得到多态性,例如template <typename T> void poly(T& t) { t.f(); }要求对每个实例化静态多态调度到t.f()

    关于c++ - C++中是否存在真正的静态多态性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20781527/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com