Что конкретно представляет собой цель С++ в стиле функций?
Я говорю о типах "тип (значение)" - стиле. Книги, которые я прочитал, быстро переходят через них, говоря только о том, что они семантически эквивалентны стилям в стиле C, "(type) value" и что их следует избегать. Если они означают то же самое, что делает старинный стиль, почему они когда-либо добавлялись к языку? Кроме того, поскольку декларации могут содержать избыточные круглые скобки, этот код: "T x (T (y)); не делает того, что ожидал бы кто-то, кто намеревался использовать функции-функции; он объявляет функцию с именем x, принимающей T и возвращающую T, а не строит переменную T с именем x, отбрасывая y на T.
Были ли они ошибкой в дизайне языка?
Ответы
Ответ 1
Приведение типов функций приводит к согласованности с примитивными и определенными пользователем типами. Это очень полезно при определении шаблонов. Например, возьмите этот очень глупый пример:
template<typename T, typename U>
T silly_cast(U const &u) {
return T(u);
}
Моя функция silly_cast
будет работать для примитивных типов, потому что это функция-стиль. Он также будет работать для определенных пользователем типов, если класс T имеет один конструктор аргументов, который принимает U или U const &.
template<typename T, typename U>
T silly_cast(U const &u) {
return T(u);
}
class Foo {};
class Bar {
public:
Bar(Foo const&) {};
};
int main() {
long lg = 1L;
Foo f;
int v = silly_cast<int>(lg);
Bar b = silly_cast<Bar>(f);
}
Ответ 2
Цель их состоит в том, чтобы вы могли передать более одного аргумента конструктору класса:
T(a1, a2); // call 2-argument constructor
(T)(a1, a2); // would only pass a2.
Не существует механизма, при котором стиль (T) expr
может передавать несколько аргументов, поэтому необходима новая форма преобразования. Естественно определить (T) expr
как вырожденный случай T(expr)
.
В отличие от того, что говорят некоторые люди, (T) expr
работает точно так же, как T(expr)
, поэтому он будет отлично работать с типами классов.
Ответ 3
Несколько проще разобрать приведение в стиле функции в языке, где скобки уже используются (более).
Были ли они ошибкой? Возможно, но только в той мере, в какой они не смогли полностью вытеснить отливки в стиле C и, следовательно, предоставили механизм для каста Perl-like "там более чем один способ сделать это". С явным и отличительным современным отбрасыванием:
dynamic_cast<type>(value);
reinterpret_cast<type>(value);
static_cast<type>(value);
const_cast<type>(value);
нет причин использовать C-style casts больше и меньше оснований использовать функции в стиле casts.
Ответ 4
Приведения в стиле C не должны использоваться.
Следует использовать приведения в стиле функций, особенно если целевой тип - это имя класса (или специализация шаблона класса). Они соответствуют шаблону кажущихся вызовов конструктора в случае с одним аргументом.
MyClass( expr ); // Creates temporary, initialized like MyClass obj( expr );
MyClass( e1, e2 ); // Similar, and no other way to write this.
int( expr ); // Function-style cast.
Ответ 5
AFAIK-функции - это расширение для родных типов обычного синтаксиса временного создания для классов: до тех пор, пока вы можете создать временный объект внутри выражения с использованием синтаксиса ClassName(parameters)
, нет причин, по которым вы должны " t сделать это с помощью родных типов. изменить Обратите внимание, что, как сказал @steve, это очень полезно в шаблонах
Обратите внимание, что однопараметрические конструкторы в С++ часто так или иначе "ощущаются" как объекты преобразования, см., например, синтаксис (конструктор преобразования), который позволяет вам инициализировать новый объект с помощью знака равенства, за которым следует значение
ClassName MyObject = 3;
что на самом деле означает
ClassName MyObject(3);
и (предположительно) вызывает конструктор one- int
-параметра ClassName.
Кстати, здесь хорошая страница о приведениях в стиле функции.
Ответ 6
Что это за книга? Это касты C-стиля, которые, как правило, считаются плохой идеей. Самый современный код на С++ выглядит так (когда требуется бросок)
x = sometype( y );
а не
x = (sometype) y;
Помимо всего прочего, прежний синтаксис больше похож на вызов конструктора, который в большинстве случаев, вероятно, есть, хотя две формы на самом деле семантически идентичны.