Подтвердить что ты не робот

Что конкретно представляет собой цель С++ в стиле функций?

Я говорю о типах "тип (значение)" - стиле. Книги, которые я прочитал, быстро переходят через них, говоря только о том, что они семантически эквивалентны стилям в стиле C, "(type) value" и что их следует избегать. Если они означают то же самое, что делает старинный стиль, почему они когда-либо добавлялись к языку? Кроме того, поскольку декларации могут содержать избыточные круглые скобки, этот код: "T x (T (y)); не делает того, что ожидал бы кто-то, кто намеревался использовать функции-функции; он объявляет функцию с именем x, принимающей T и возвращающую T, а не строит переменную T с именем x, отбрасывая y на T.

Были ли они ошибкой в ​​дизайне языка?

4b9b3361

Ответ 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;

Помимо всего прочего, прежний синтаксис больше похож на вызов конструктора, который в большинстве случаев, вероятно, есть, хотя две формы на самом деле семантически идентичны.