Ошибки округления с плавающей запятой. 0,1 не могут быть представлены точно в базе-2, как в базе-10, из-за недостающего простого коэффициента 5. Так же, как 1/3 принимает бесконечное число цифр для представления в десятичной форме, но составляет «0,1» в базе-3, 0.1 принимает бесконечное число цифр в базе-2, где оно не находится в базе-10. И компьютеры не имеют бесконечного объема памяти.
Самый неприятный синтаксический разбор
Это связано с тем, что известно как «самый неприятный синтаксис C ++». В принципе, все, что может интерпретировать компилятор как объявление функции, будет интерпретироваться как объявление функции.
Другой экземпляр той же проблемы:
std::ifstream ifs("file.txt");
std::vector<T> v(std::istream_iterator<T>(ifs), std::istream_iterator<T>());
v
интерпретируется как объявление функции с двумя параметрами.
Обходной путь заключается в добавлении еще одной пары круглых скобок:
std::vector<T> v((std::istream_iterator<T>(ifs)), std::istream_iterator<T>());
Или, если у вас есть C ++ 11 и инициализация списка (также известная как равномерная инициализация):
std::vector<T> v{std::istream_iterator<T>{ifs}, std::istream_iterator<T>{}};
При этом нет возможности интерпретировать его как объявление функции.
Поскольку он рассматривается как объявление для функции:
int MyFunction(); // clearly a function
MyObject object(); // also a function declaration
Из n4296 [dcl.init]:
[Примечание: поскольку
blockquote>()
не разрешено синтаксисом для инициализатора ,X a();
не является объявление объекта класса X, но объявление функции не принимает аргумента и возвращает X. Форма () разрешена в некоторых других контекстах инициализации (5.3. 4, 5.2.3, 12.6.2). -End note]
Я думаю, компилятор не знал бы, будет ли этот оператор:
MyObject object ();
blockquote>- это вызов конструктора или прототип функции, объявляющий функцию с именем object с возвращаемым типом MyObject и без параметров.
Вы также можете использовать более подробный способ построения:
MyObject object1 = MyObject();
MyObject object2 = MyObject(object1);
В C ++ 0x это также позволяет использовать auto
:
auto object1 = MyObject();
auto object2 = MyObject(object1);
Поскольку компилятор считает, что это объявление функции, которая не принимает аргументов и возвращает экземпляр MyObject.
Как говорили другие, это объявление функции. Начиная с C ++ 11 вы можете использовать инициализацию скобки, если вам нужно увидеть пустое something , которое явно сообщает вам, что используется конструктор по умолчанию.
Jedi luke{}; //default constructor
Как уже упоминалось много раз, это декларация. Это способ обратной совместимости. Одна из многих областей C ++, которая является тупой / непоследовательной / болезненной / фиктивной из-за ее наследия.
Тот же синтаксис используется для объявления функции - например, функция object
, не принимая параметров и возвращая MyObject