Обсуждение:C++11
Эта статья тематически связана с вики-проектом «Информационные технологии», цель которого — создание и улучшение статей по темам, связанным с информационными технологиями. Вы можете её отредактировать, а также присоединиться к проекту, принять участие в его обсуждении и поработать над требуемыми статьями. |
Untitled
[править код]Мнится мне, что на английском эта статья будет понятнее, ибо русский текст просто набор бессмысленных предложений. Придётся читать английскую версию:(
Неясности
[править код]конструктор переноса
std::vector::vector(vector &&x)
может просто перенести указатель и длину в новый объект, опустошивx
[ЩИТО?].
Что это значит? Будет ли вызван деструктор, если конструктор вызывается при приведении типов? Что значит "просто перенести"?
С какимим целями введён в стандарт constexpr
? Не для чего, а почему? Особенно интересно зачем для функций.
Тривиальный класс — это класс, который: содержит тривиальный конструктор по умолчанию,
Гениально. X is so X.
А что такое "тривиальный конструктор" и прочие "тривиальности"?
Во-первых, определение явно инициализируемой переменной может содержать ключевое слово auto.
1. Пожалуй, стоит указать, что ключевое слово auto существовало в прошлом стандарте, но здесь его значение изменено.
2. Не совсем понятно, как программисту работать с типом, которого он не знает, в случае с контейнером в примере (auto someStrangeCallableType = std::bind(&SomeFunction, _2, _1, someObject);
).
for(int &x : my_array)
Похоже, следующий стандарт будет Perl.
109.161.90.147 16:50, 31 августа 2013 (UTC)
/Неясности
[править код]В тексте статьи использована фраза - "Например, std::vector — это простая обёртка вокруг Си-массива и переменной, хранящей его размер."
Позволю себе не согласиться. Стандарт С++ никоим образом не описывает внутреннее представление std::vector. Он лишь описывает интерфейс взаимодействия.
В частности современные реализации vector'a довольно сложны, и могут содержать внутри себя списки блоков данных (linked lists). О простоте тут речи быть не может.
178.121.121.16 00:06, 11 августа 2012 (UTC)
- Вообще-то, стандарт гарантирует, что элементы вектора располагаются последовательно в одном болке памяти. 77.247.211.6 11:10, 9 января 2014 (UTC)
Плохие примеры
[править код]В статье используются примеры, содержащие типичные ошибки программирования. Например, переписанная функция printf():
void printf(const char *s)
{
while (*s) {
if (*s == '%' && *(++s) != '%')
throw std::runtime_error("invalid format string: missing arguments");
std::cout << *s++;
}
}
template<typename T, typename... Args>
void printf(const char *s, T value, Args... args)
{
while (*s) {
if (*s == '%' && *(++s) != '%') {
std::cout << value;
++s;
printf(s, args...); // продолжаем обработку аргументов, даже если *s == 0
return;
}
std::cout << *s++;
}
throw std::logic_error("extra arguments provided to printf");
}
может повести себя неопределëнным образом при вызове printf("%", "str1", "str2")
.178.130.5.13 22:07, 10 апреля 2012 (UTC)
- ВП:Правьте смело. Приведите свои примеры, которые на ваш взгляд лучше для данной статьи. Все будут только рады. --Dnikitin 05:51, 11 апреля 2012 (UTC)
- К сожалению, я почти не знаю C++11, поэтому и читал эту статью.178.130.5.13 12:50, 18 апреля 2012 (UTC)
Также иногда используются имена переменных, более характерных для java-coding-style, чем для c-style.
Например, имя переменной moonGravity более характерно для java, для c более употребимо moon_gravity
176.109.125.244 09:44, 27 мая 2012 (UTC)
Добавить в раздел "Константа нулевого указателя"
[править код]Следует добавить ещё один пример вредосности NULL в С++.
Иногда программисту С++ приходится писать функции с переменным числом параметров.
Рассмотрим пример добавления дочерних виджетов для какого-то "окна":
// принимает список дочерних элементов текущего окна. конец списка - NULL
void Widget::AddChildWidgets(...);
Widget myWindow;
Button btn1, btn2;
Scrollbar scroll1;
myWindow.AddChildWidgets(&btn1, &btn2, &scroll1, NULL);
Данный код абсолютно корректен для платформы i386. Дело в том что sizeof(Widget*)=4. А ещё sizeof(NULL)=sizeof(int)=4 , так как NULL=0.
Но это совершенно не работает для платформы AMD64. Дело в том что sizeof(Widget*)=8. А ещё sizeof(NULL)=sizeof(int)=4 , так как NULL=0.
В последнем случае на стек ляжет только 4 байта вместо положенных 8. Функция AddChildWidgets благополучно извлечёт со стека 8 байт. Разумеется из них только 4 байта будут равны нулю, то есть как минимум функция ошибётся с количеством ей переданных параметров, и будет продолжать читать машинный стек пока не нарвётся на 8 подряд идущих нулевых байт либо пока не сработает аппаратная защита. Ну и конечно же все полученные указатели, начиная с 4-го будут некорректными и попытка сделать что-либо с ними полезное (вызов функции или чтение/модификация данных) вызовет ошибку доступа к памяти.
Одно из требований, предъявляемых к указателю nullptr (в стандарте это оговорено, но в данной статье не написано) это гарантия справедливости выражения:
sizeof(nullptr)=sizeof(void*)=sizeof(указатель любого типа).
Таким образом заменив выше приведённый пример на myWindow.AddChildWidgets(&btn1, &btn2, &scroll1, nullptr);
мы добъёмся его полной работоспособности на любой платформе.
Следует также отметить что nullptr может быть реализован программно в виде подключаемого заголовочного файла (для тех компиляторов и/или их версий, которые пока что не поддерживают nullptr на уровне языка). В интернете можно найти несколько подобных реализаций. Однако следует быть внимательным - для многих таких доморощенных реализаций не соблюдается правило размерности указателя и nullptr. 178.121.121.16 23:42, 10 августа 2012 (UTC)