вот код:
cout.operator<<("Hello");//он выводит вместо строки какие-то шестнадцетиричные числа 01337BD8P
фактически тот же самый код:
cout << "Hello";//выводит строку
operator<<(cout,"Hello");//тоже выводит строку
В чем разница между записями?
basic_ostream для указателей существует несколько перегрузок operator<<. Часть из этих перегрузок выполнена в качестве функций-членов класса, а часть как внешние функции.
В определении самого класса для указательных типов имеется только перегрузка для параметра типа void *
template<class charT, class traits = char_traits<charT>>
class basic_ostream : virtual public basic_ios<charT, traits> {
public:
...
basic_ostream<charT, traits>& operator<<(const void* p);
...
};
При вызове
cout.operator<<("Hello");
вызывается именно функция-член класса, а других подходящих вариантов перегрузки нет:
"Hello"
- массив char[6]
, который может быть неявно преобразован в char const *
, который в свою очередь преобразуется в void const *
поэтому и выводится адрес, в соответствии с поведением данной перегрузки.
Перегрузки, принимающие char const *
объявлены как внешние функции:
template<class charT, class traits>
basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>&, const char*);
template<class traits>
basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const char*);
В коде
operator<<(cout, "Hello");
явно вызывается внешняя функция operator<<
, поэтому функции-члены basic_ostream
даже не рассматриваются. Естественно, это приводит к выводу строки в соответствии с поведением перегрузки для char const *
Код
cout << "Hello";
приводит к рассмотрению перегрузок operator<<
объявленных как функции-члены basic_ostream
, и как внешних функций.
При выборе соответствующих перегрузок, перегрузка с параметром char const *
оказывается более подходящей, чем остальные, поэтому выбирается соответствующая внешняя операторная функция.
Для классов большинство операторов вида X ■ Y
(включая <<
) можно перегружать двумя способами:
struct A { … operator■(…){…} };
struct A {}; int operator■(…, …){…}
Когда вы пишете X.operator■(Y)
, компилятор учитывает только те перегрузки ■
, которые сделаны в виде методов.
Когда вы пишете operator■(X, Y)
, компилятор учитывает только те перегрузки, которые сделаны в виде свободных функций.
Когда вы пишете X ■ Y
, компилятор учитывает оба варианта перегрузок.
Похоже, что для std::cout
оператор <<
для разных типов перегружен разными способами.
Для const char *
(печать строки) он перегружен как свободная функция, а для const void *
(печать адреса) он перегружен как метод.
Когда вы пишете cout << "Hello";
, выбирается перегрузка с параметром const char *
(свободная функция), потому что она подходит лучше, чем та, что с параметром const void *
(метод), и чем все остальные варианты.
Когда вы пишете operator<<(cout,"Hello");
, рассматриваются только перегрузки в виде свободных функций. Из них выбирается та же самая перегрузка, с параметром const char *
. А вариант с параметром const void *
не рассматривается вообще, потому что это - метод.
А вот когда вы пишете cout.operator<<("Hello");
, вариант с const char *
не рассматривается, и из перегрузок-методов выбирается const void *
, потому что он подходит лучше других вариантов.
Виртуальный выделенный сервер (VDS) становится отличным выбором
myDequeerase(min) выдает ошибку: cannot seek value-initialized deque iterator
Есть ли встроенные методы, позволяющие сравнить изображения на полное сходство (Не просто == или imgequals(img2), ибо в первом это разные объекты,...
Был у меня recyclerview с адаптером и все было крутоЯ добавил view