Что такое полиморфизм времени компиляции и почему он применяется только к функциям?Что такое полиморфизм времени компиляции и почему он применяется только к функциям?
ответ
Возвращение назад, когда «полиморфизм времени компиляции» означает перегрузку функции. Это относится только к функциям, потому что они все, что вы можете перегрузить.
В текущем C++ шаблоны меняют это. Нил Баттерворт уже привел один пример. Другой использует специализированную специализацию. Например:
#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;
}
Это должно дать 42
, 0
и ""
(пустая строка) - мы получаем структуру, которая действует по-разному для каждого типа.
Здесь у нас есть «полиморфизм времени компиляции» классов вместо функций. Я полагаю, что если вы хотите аргументировать эту точку зрения, вы можете утверждать, что это хотя бы частично результат конструктора (функции) хотя бы в одном случае, но в специализированной версии my_template
нет , есть конструктор.
Редактировать: Что касается того, почему это полиморфизм. Я поставил «полиморфизм времени компиляции» в кавычки по какой-то причине - он несколько отличается от обычного полиморфизма. Тем не менее, мы получаем эффект, подобный тому, что мы могли бы ожидать от перегрузки функций:
int value(int x) { return 0; }
long value(long x) { return 42; }
std::cout << value(1);
std::cout << value(1L);
Перегрузка функций и специализация дают аналогичные эффекты. Я согласен с тем, что вопрос о том, применим ли «полиморфизм» к какому-либо другому, может быть открытым, но я думаю, что он применим одинаково хорошо к одному, как к другому.
Термин компиляция полиморфизма времени немного расплывчата, можете ли вы подробнее рассказать о том, как вы думаете, что ваш пример полиморфен? Я все еще нахожусь на заборе, потому что это или не является полиморфизмом. Я бы предположил, что полиморфной частью этого примера является перегрузка оператора '<<' для 'std :: ostream'. Следует ли рассматривать экземпляр шаблона как своего рода абстрактную функцию, где тип является аргументом? –
Как бы вы утверждали, что полиморфизм не применяется? Полимофизм означает либо «много форм». В примерах (и при перегрузке функций) один и тот же переключатель функций приводит к нескольким различным «формам» функции. –
Полиморфизм времени компиляции применяется к функциям и перегрузкам оператора.
Читать эту http://cpp-tutorial.cpp4u.com/OOP_polymorphism.html
время компиляции полиморфизм это термин, который относится к шаблону программирования C++. Например, во время компиляции вы определить фактический тип станд :: вектор тем, что он содержит:
std::vector <int> vi;
std::vector <std::string> vs;
Я не знаю, почему вы думаете, что она ограничена функциями.
С компиляцией времени полиморфизма один обычно означает тот факт, что вы можете иметь несколько функций с тем же именем и компилятором будет выбрать во время компиляции, который один для использования в зависимости от аргументов:
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
Функции foo
считается перегруженным. Различные типы экземпляров шаблона также можно назвать полиморфизмом времени компиляции.
Проклятье, избили меня. – wheaties
Как насчет шаблонов классов? Компилятор выбирает, какую версию класса следует создавать на основе типа T, который мы предоставляем, так ли это означает, что шаблоны классов также отображают полиморфное поведение времени компиляции? – captonssj
@captonssj, я бы сказал, что да, они это делают. – Omnifarious
Вещь, применимая только к функциям, является вычитанием параметра шаблона. Если у меня есть шаблон функции:
template <typename T>
void foo(T &t);
Тогда я могу сделать int a = 0; foo(a);
, и это будет эквивалентно int a = 0; foo<int>(a);
. Компилятор работает, я имею в виду foo<int>
. По крайней мере, выясняется, что он должен использовать foo<int>
- если это не то, что я имел в виду, тогда мне не повезло, и я мог бы написать foo<unsigned int>(a);
или что-то еще.
Однако, если у меня есть шаблон класса:
template <typename T>
struct Foo {
T &t;
Foo(T &t) : t(t) {}
T &getT() { return t; }
};
Тогда я не могу сделать int a = 0; Foo(a).getT();
. Я должен указать Foo<int>(a)
. Компилятору не разрешено работать, я имею в виду Foo<int>
.
Итак, вы можете сказать, что шаблоны классов «менее полиморфны», чем шаблоны функций. Полиморфизм обычно означает, что вам не нужно писать код, чтобы сделать тип вашего объекта явным. Шаблоны функций позволяют это (в данном конкретном случае), а шаблоны классов - нет.
Что касается того, почему это так - стандарт говорит так, я не знаю почему. Обычными подозреваемыми являются (а) это слишком сложно реализовать, (б) это не полезно, по мнению стандартного комитета, или (в) создает какое-то противоречие или двусмысленность в другом месте на этом языке.
Но вы все еще можете сделать другие виды полиморфизма классов:
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]);
}
}
};
Это, как правило, также называется время компиляции полиморфизм, потому что, насколько автор шаблона обеспокоен, t.handleOne
может быть что угодно, и что это будет, когда это необходимо, будет разрешено «позже» в компиляции при создании экземпляра Foo.
Я думаю, что это полезно в соответствии со стандартным комитетом, потому что они решили обойти эту конкретную проблему с реализацией std :: mem_fun/std :: mem_fun_t.В основном то, что они сделали: шаблон <имяТипа _Tx> станд :: mem_fun_t <_Tx> mem_fun (Const _Tx & т) { возвращение станд :: mem_fun_t <_Tx> (т); } –
Да, и то же самое с итераторными адаптерами: 'back_inserter' возвращает' back_insert_iterator'. Когда я сказал «и», я имел в виду «это список», а не «все это правда». Я думаю, что (а) тоже маловероятно, так что это либо (с), либо «без уважительной причины». –
Вопрос выглядит в значительной степени полностью встроенным в учебник. –
Можете ли вы описать противоречие, которое видите? - Возможно, это помогает ответить на фактический вопрос, который у вас есть. – johannes
В моем учебнике есть какая-то двусмысленность, или я не понимаю, что я читаю, поэтому я решил, что прошу здесь. – ihtkwot