C++ 什么是编译时多态性,为什么它只适用于函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1881468/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:28:40  来源:igfitidea点击:

What is compile-time polymorphism and why does it only apply to functions?

c++polymorphismcompile-time

提问by ihtkwot

What is compile-time polymorphism and why does it only apply to functions?

什么是编译时多态性,为什么它只适用于函数?

采纳答案by Jerry Coffin

Way back when, "compile time polymorphism" meant function overloading. It applies only to functions because they're all you can overload.

回到“编译时多态”意味着函数重载的时代。它仅适用于函数,因为它们是您可以重载的全部。

In current C++, templates change that. Neil Butterworth has already given one example. Another uses template specialization. For example:

在当前的 C++ 中,模板改变了这一点。Neil Butterworth 已经举过一个例子。另一个使用模板专业化。例如:

#include <iostream>
#include <string>

template <class T>
struct my_template { 
    T foo;
    my_template() : foo(T()) {}
};

template <>
struct my_template<int> {
    enum { foo = 42 };
};

int main() { 
    my_template<int> x;
    my_template<long> y;
    my_template<std::string> z;
    std::cout << x.foo << "\n";
    std::cout << y.foo << "\n";
    std::cout << "\"" << z.foo << "\"";
    return 0;
}

This should yield 42, 0, and ""(an empty string) -- we're getting a struct that acts differently for each type.

这应该产生42, 0, 和""(一个空字符串)——我们得到一个对每种类型都有不同作用的结构。

Here we have "compile time polymorphism" of classes instead of functions. I suppose if you wanted to argue the point, you could claim that this is at least partially the result of the constructor (a function) in at least one case, but the specialized version of my_templatedoesn't even havea constructor.

这里我们有类而不是函数的“编译时多态性”。我想如果你想争论这一点,你可以声称这至少在一种情况下至少部分是构造函数(一个函数)的结果,但 的专门版本my_template甚至没有构造函数。

Edit: As to why this is polymorphism. I put "compile time polymorphism" in quotes for a reason -- it's somewhat different from normal polymorphism. Nonetheless, we're getting an effect similar to what we'd expect from overloading functions:

编辑:至于为什么这是多态性。我将“编译时多态性”放在引号中是有原因的——它与普通的多态性有些不同。尽管如此,我们得到的效果类似于我们对重载函数的期望:

int value(int x) { return 0; }
long value(long x) { return 42; }

std::cout << value(1);
std::cout << value(1L);

Function overloading and specialization are giving similar effects. I agree that it's open to some question whether "polymorphism" applies to either, but I think it applies about equally well to one as the other.

函数重载和专业化产生了类似的效果。我同意“多态性”是否适用于任何一个的问题是开放的,但我认为它同样适用于一个和另一个。

回答by Andreas Brinck

With compile time polymorphism one usually means the fact that you can have a several functions with the same name and the compiler will choose at compile time which one to used depending on the arguments:

编译时多态性通常意味着您可以拥有多个同名函数,编译器将在编译时根据参数选择使用哪一个:

void foo(int x);
void foo(float y);

//Somewhere else
int x = 3;
foo(x); //Will call first function
float y = 2;
foo(y); //Will call second function

The function foois said to be overloaded. Various types of template instantiation could also be called compile time polymorphism.

该函数foo被称为重载。各种类型的模板实例化也可以称为编译时多态。

回答by Andreas Brinck

Compile time polymorphism is a term that refers to C++ template programming. For example, at compile time you determine the actual type of a std::vector by what it contains:

编译时多态性是一个术语,指的是 C++ 模板编程。例如,在编译时,您可以通过 std::vector 包含的内容来确定它的实际类型:

std::vector <int> vi;
std::vector <std::string> vs;

I'm not sure why you think it it is limited to functions.

我不确定为什么您认为它仅限于功能。

回答by Steve Jessop

The thing which only applies to functions is template parameter deduction. If I have a function template:

仅适用于函数的是模板参数推导。如果我有一个函数模板:

template <typename T> 
void foo(T &t);

Then I can do int a = 0; foo(a);, and this will be equivalent to int a = 0; foo<int>(a);. The compiler works out that I mean foo<int>. At least, it works out that it should use foo<int>- if that's not what I meant then bad luck to me, and I could have written foo<unsigned int>(a);or whatever.

然后我可以做int a = 0; foo(a);,这将相当于int a = 0; foo<int>(a);. 编译器计算出我的意思是foo<int>. 至少,它应该使用它foo<int>- 如果这不是我的意思,那么对我来说运气不好,我可以写foo<unsigned int>(a);或其他什么。

However, if I have a class template:

但是,如果我有一个类模板:

template <typename T>
struct Foo {
    T &t;
    Foo(T &t) : t(t) {}
    T &getT() { return t; }
};

Then I can't do int a = 0; Foo(a).getT();. I have to specify Foo<int>(a). The compiler isn't allowed to work out that I mean Foo<int>.

然后,我不能这样做int a = 0; Foo(a).getT();。我必须指定Foo<int>(a). 不允许编译器计算出我的意思是Foo<int>.

So you might say that class templates are "less polymorphic" than function templates. Polymorphism usually means that you don't have to write code to make the type of your object explicit. Function templates allow that (in this particular case), and class templates don't.

所以你可能会说类模板比函数模板“更少多态”。多态性通常意味着您不必编写代码来明确对象的类型。函数模板允许(在这种特殊情况下),而类模板不允许。

As for why this is the case - the standard says so, I don't know why. The usual suspects are (a) it's too difficult to implement, (b) it's not useful, in the opinion of the standard committee, or (c) it creates some contradiction or ambiguity somewhere else in the language.

至于为什么会这样——标准是这样说的,我不知道为什么。通常的怀疑是(a)它太难实施,(b)它没有用,在标准委员会看来,或者(c)它在语言的其他地方造成了一些矛盾或歧义。

But you can still do other kinds of polymorphism with classes:

但是您仍然可以对类进行其他类型的多态:

template <typename T>
struct Foo {
    T &t;
    Foo(T &t): t(t) {}
    void handleMany(int *ra, size_t s) {
        for (size_t i = 0; i < s; ++i) {
            t.handleOne(ra[i]);
        }
    }
};

This is usually also called compile-time polymorphism, because as far as the author of the template is concerned, t.handleOnecould be anything, and what it is will be resolved when necessary, "later" in the compilation when Foo is instantiated.

这通常也称为编译时多态性,因为就模板的作者而言,它t.handleOne可以是任何东西,并且在必要时会在编译时“稍后”在实例化 Foo 时解析它。

回答by randomThought

Compile time polymorphism applies to functions and operator overloads.

编译时多态适用于函数和运算符重载。

Read this http://cpp-tutorial.cpp4u.com/OOP_polymorphism.html

阅读这个http://cpp-tutorial.cpp4u.com/OOP_polymorphism.html