Что именно является или было целью приведения типов в C ++? - PullRequest
25 голосов
/ 18 декабря 2010

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

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

Ответы [ 6 ]

24 голосов
/ 18 декабря 2010

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

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);
}
10 голосов
/ 18 декабря 2010

Их цель в том, чтобы вы могли передать более одного аргумента в конструктор класса:

T(a1, a2); // call 2-argument constructor
(T)(a1, a2); // would only pass a2.

Не существует механизма, который приведения типа (T) expr мог бы передавать несколько аргументов,поэтому нужна была новая форма обращения.Естественно определить (T) expr как вырожденный случай T(expr).

Вопреки тому, что некоторые здесь говорят, (T) expr работает точно так же, как T(expr), поэтому он будет отлично работать и с типами классов.

7 голосов
/ 18 декабря 2010

Несколько проще проанализировать приведение типов функций в языке, где круглые скобки уже используются (чрезмерно).

Были ли они ошибкой?Возможно - но только в той мере, в которой они не смогли полностью заменить броски в стиле C, и, следовательно, предоставили Perl-подобный механизм «существует несколько способов сделать это» для приведения.С явными и отличительными современными приведениями:

dynamic_cast<type>(value);
reinterpret_cast<type>(value);
static_cast<type>(value);
const_cast<type>(value);

больше нет причин использовать приведение в стиле C, и меньше оснований для использования приведений в стиле функции.

3 голосов
/ 18 декабря 2010

Приведения типов в стиле 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.
1 голос
/ 18 декабря 2010

Приведения типов в стиле AFAIK являются расширением собственных типов обычного синтаксиса временного создания классов: если вы можете создать временный объект внутри выражения с использованием синтаксиса ClassName(parameters), нет причин, по которым вы не должны ' сделать это с нативными типами. edit Обратите внимание, что, как сказал @steve, это очень полезно в шаблонах

Обратите внимание, что однопараметрические конструкторы в C ++ часто так или иначе "чувствуются" как средства преобразования, см., Например, синтаксис ( конструктор преобразования ), который позволяет инициализировать новый объект, используя знак равенства, за которым следует знак значение

ClassName MyObject = 3;

что на самом деле означает

ClassName MyObject(3);

и (предположительно) вызывает конструктор класса OneName * int.

Кстати, здесь хорошая страница о приведениях в функциональном стиле.

0 голосов
/ 18 декабря 2010

Какая это была книга ???Это броски в стиле C, которые обычно считаются плохой идеей.Самый современный код C ++ выглядит следующим образом (когда требуется приведение)

x = sometype( y );

, а не

x = (sometype) y;

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

...