Кто нибудь понимает код STL от MS?
От: Juster  
Дата: 19.09.14 04:51
Оценка: :))) :)
Я когда туда заглядываю, мне сразу закрыть хочется. Такое ощущение, что код был создан авто-генератором каким-то, форматирование неудобное, имена жутко запутанные, структура довольно сложная. Кто-то в этом разбирается? Я уж про буст не говорю, там пока разберешься во всех typedef, ifdef, все ногти перекусаешь
Re: Кто нибудь понимает код STL от MS?
От: Хон Гиль Дон Россия  
Дата: 19.09.14 05:19
Оценка: +2 -1
Здравствуйте, Juster, Вы писали:

J>Я когда туда заглядываю, мне сразу закрыть хочется. Такое ощущение, что код был создан авто-генератором каким-то, форматирование неудобное, имена жутко запутанные, структура довольно сложная. Кто-то в этом разбирается?


Кстати, автор этого кода, P. J. Plauger, в соавторстве со всем известным Керниганом написал книжку по хорошему стилю оформления кода — The Elements of Programming Style, "...advocating the notion that computer programs should be written not only to satisfy the compiler or personal programming "style", but also for "readability" by humans, specifically software maintenance engineers, programmers and technical writers."

Вообще, ничего там сложного, просто стиль форматирования довольно редкий и имена начинаются с подчеркивания и большой буквы, как и положено для стандартной библиотеки.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re: Кто нибудь понимает код STL от MS?
От: Qbit86 Кипр
Дата: 19.09.14 07:51
Оценка: :))
Здравствуйте, Juster, Вы писали:

J>код STL от MS?


Код STL от Microsoft писался в Dinkumware.

J>Кто нибудь понимает код STL?


Код STL понимает STL.
Глаза у меня добрые, но рубашка — смирительная!
Re: Кто нибудь понимает код STL от MS?
От: HolyNick  
Дата: 19.09.14 08:53
Оценка:
Это дело опыта. Просто нужно потрать некоторое время.
Re: Кто нибудь понимает код STL от MS?
От: Abyx Россия  
Дата: 19.09.14 08:58
Оценка: +1
Здравствуйте, Juster, Вы писали:

J>Я когда туда заглядываю, мне сразу закрыть хочется. Такое ощущение, что код был создан авто-генератором каким-то, форматирование неудобное, имена жутко запутанные, структура довольно сложная. Кто-то в этом разбирается? Я уж про буст не говорю, там пока разберешься во всех typedef, ifdef, все ногти перекусаешь


ну да, понимаем. и буст тоже. а что там сложного-то? в стандартной библиотеке обычный код, только все имена с __ или _X
In Zen We Trust
Re: Кто нибудь понимает код STL от MS?
От: Кодт Россия  
Дата: 19.09.14 09:22
Оценка: 6 (1) +1
Здравствуйте, Juster, Вы писали:

J>Я когда туда заглядываю, мне сразу закрыть хочется. Такое ощущение, что код был создан авто-генератором каким-то, форматирование неудобное, имена жутко запутанные, структура довольно сложная. Кто-то в этом разбирается? Я уж про буст не говорю, там пока разберешься во всех typedef, ifdef, все ногти перекусаешь


Понимаю, причём понимаю также, откуда там ноги растут.

Это библиотека, идущая вместе с компилятором, и отвечающая двум требованиям:
— чтобы компилировалась как можно быстрее (отсюда — короткие имена)
— чтобы не смешивалась с пользовательскими библиотеками (отсюда — имена в зарезервированном для компилятора формате: _Caps и __doubleunderscore)

Очень может быть, что она исходно написана по-человечески, а потом на неё натравили обфускатор.

Ну а алгоритмическая часть там довольно прозрачная.
Единственно, что некоторые места унаследованы с древних времён, и там, где можно было бы обойтись новомодными штучками вроде decltype, используются многоэтажные диспетчеризации.

Но у меня двадцать лет опыта, в том числе, регулярного заглядывания за кулисы системных библиотек. Могу только посочувствовать тем, кто туда впервые сунулся.
Перекуём баги на фичи!
Re[2]: Кто нибудь понимает код STL от MS?
От: Evgeny.Panasyuk Россия  
Дата: 19.09.14 09:27
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Очень может быть, что она исходно написана по-человечески, а потом на неё натравили обфускатор.


Степанов в одном из выступлений (где именно не помню, если вспомню то скину) рассказывал что некий тип взял его код, пропустил через pretty-printer, а потом продал Microsoft за много $.
Re: Кто нибудь понимает код STL от MS?
От: jazzer Россия Skype: enerjazzer
Дата: 19.09.14 10:16
Оценка:
Здравствуйте, Juster, Вы писали:

J>Я когда туда заглядываю, мне сразу закрыть хочется. Такое ощущение, что код был создан авто-генератором каким-то, форматирование неудобное, имена жутко запутанные, структура довольно сложная. Кто-то в этом разбирается? Я уж про буст не говорю, там пока разберешься во всех typedef, ifdef, все ногти перекусаешь


Да там просто все, что в СТЛ, что в бусте, причем в бусте или и имена вменяемые... Главное — повыкидывать из поля зрения всякие не относящиеся к тебе ifdef-ы — они нужны, только чтоб поддерживать ту кучу платформ и компиляторов, которые они поддерживают, включая древние версии GCC и MSVC (и борланда, ага). Сейчас понемножку убирают поддержку старья, но то, что уже написано, пока что там лежит.
В общем, можешь либо через препроцессор пропустить, либо редактор настроить, чтоб определенные ifdef/endif сворачивал или другим цветом показывал, чтоб они в глаза не лезли — после этого все будет просто.

Например, файл common_type.hpp для C++11 выдает (g++ --std=c++11 -E -fdirectives-only):
  Скрытый текст
namespace boost {
// prototype
    template<typename... T>
    struct common_type;
// 1 arg
    template<typename T>
    struct common_type<T>
    {
        BOOST_COMMON_TYPE_STATIC_ASSERT(sizeof(T) > 0, BOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (T));
    public:
        typedef T type;
    };
// 2 args
namespace type_traits_detail {
    template <class T, class U>
    struct common_type_2
    {
    private:
        BOOST_COMMON_TYPE_STATIC_ASSERT(sizeof(T) > 0, BOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (T));
        BOOST_COMMON_TYPE_STATIC_ASSERT(sizeof(U) > 0, BOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (U));
        static bool declval_bool();  // workaround gcc bug; not required by std
        static typename add_rvalue_reference<T>::type declval_T();  // workaround gcc bug; not required by std
        static typename add_rvalue_reference<U>::type declval_U();  // workaround gcc bug; not required by std
        static typename add_rvalue_reference<bool>::type declval_b();
    public:
        typedef decltype(declval<bool>() ? declval<T>() : declval<U>()) type;
    };
    template <class T>
    struct common_type_2<T, T>
    {
        typedef T type;
    };
    }
    template <class T, class U>
    struct common_type<T, U>
    : public type_traits_detail::common_type_2<T,U>
    { };
// 3 or more args
    template<typename T, typename U, typename... V>
    struct common_type<T, U, V...> {
    public:
        typedef typename common_type<typename common_type<T, U>::type, V...>::type type;
    };
}  // namespace boost

а для С++03 (g++ --std=c++03 -E -fdirectives-only):
  Скрытый текст
namespace boost {
// prototype
    template <class T, class U = void, class V = void>
    struct common_type
    {
    public:
        typedef typename common_type<typename common_type<T, U>::type, V>::type type;
    };
// 1 arg
    template<typename T>
    struct common_type<T, void, void>
    {
        BOOST_COMMON_TYPE_STATIC_ASSERT(sizeof(T) > 0, BOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (T));
    public:
        typedef T type;
    };
// 2 args
namespace type_traits_detail {
    template <class T, class U>
    struct common_type_2
    {
    private:
        BOOST_COMMON_TYPE_STATIC_ASSERT(sizeof(T) > 0, BOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (T));
        BOOST_COMMON_TYPE_STATIC_ASSERT(sizeof(U) > 0, BOOST_COMMON_TYPE_MUST_BE_A_COMPLE_TYPE, (U));
        static bool declval_bool();  // workaround gcc bug; not required by std
        static typename add_rvalue_reference<T>::type declval_T();  // workaround gcc bug; not required by std
        static typename add_rvalue_reference<U>::type declval_U();  // workaround gcc bug; not required by std
        static typename add_rvalue_reference<bool>::type declval_b();
    public:
        typedef BOOST_TYPEOF_TPL(declval_b() ? declval_T() : declval_U()) type;
    };
    template <class T>
    struct common_type_2<T, T>
    {
        typedef T type;
    };
    }
    template <class T, class U>
    struct common_type<T, U, void>
    : public type_traits_detail::common_type_2<T,U>
    { };
// 3 or more args
}  // namespace boost


Сразу видна разница в реализации для С++11 с вариадиками и для обычного С++03 с дефолтными void.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Кто нибудь понимает код STL от MS?
От: B0FEE664  
Дата: 19.09.14 10:32
Оценка: 14 (4) :)
Здравствуйте, Juster, Вы писали:

J>Я когда туда заглядываю, мне сразу закрыть хочется. Такое ощущение, что код был создан авто-генератором каким-то, форматирование неудобное, имена жутко запутанные, структура довольно сложная. Кто-то в этом разбирается? Я уж про буст не говорю, там пока разберешься во всех typedef, ifdef, все ногти перекусаешь


Понять-то можно, но вот то, что писатели (как правило) совершенно не думают о читателях или удобном использовании — это почти всегда так.
Вот вчера пытался переносимо округлить float до int...
И тут началось... Не, ну я понимаю, задача сложная, непростая... Ну, это примерно как конвертировать int в строку: тысячи идиотских примеров привязанных то к архитектуре, то к системе. Каждый год новое слово в конвертостроении.
Но я, как дисциплинированный инженер, открываю boost, нахожу boost::math::iround, читаю. Ага, может бросить исключение... Так, исключение мне не нужно. Мне даже сообщение об ошибке не нужно. Мне нужно значения выходящие за пределы пределы представления int конвертировать в минимальное и в максимальное значения. Открываю код:
template <class T, class Policy>
inline int iround(const T& v, const Policy& pol)
{
   BOOST_MATH_STD_USING
   T r = boost::math::round(v, pol);
   if((r > (std::numeric_limits<int>::max)()) || (r < (std::numeric_limits<int>::min)()))
      return static_cast<int>(policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", 0, v, 0, pol));
   return static_cast<int>(r);
}
template <class T>
inline int iround(const T& v)
{
   return iround(v, policies::policy<>());
}


вижу policy. Думаю, ну теперь-то надо просто подкрутить немного policy, подменив policies::policy<>() на что-то своё. Открываю рекомендации от авторов: о майн год! Писатели рекомендуют переопределять функции обработки ошибок прямо в пространстве имён boost::math::policies ! Это меня несколько настораживает, но не останавливает. Я довожу до конца изменения кода, компилирую и получаю с какими-то варнингами то, что мне нужно. Задаю запредельное значение и прохожу в дебагере, внезапно вижу рядом код:
template <class T, class TargetType>
inline T raise_rounding_error(
           const char* , 
           const char* , 
           const T& val, 
           const TargetType&,
           const  ::boost::math::policies::rounding_error< ::boost::math::policies::errno_on_error>&)
{
   errno = ERANGE;
   // This may or may not do the right thing, but the user asked for the error
   // to be silent so here we go anyway:
   return std::numeric_limits<T>::is_specialized ? (val > 0 ? (std::numeric_limits<T>::max)() : -(std::numeric_limits<T>::max)()): val;
}

Понимаю, что я сделал что-то лишнее. Ищу способ использовать эту функцию. Натыкаюсь на багфикс: здесь. Странно, у меня версия 1.53, а выглядит так же. Но "добило" меня это:

Caution
There is a danger of One-Definition-Rule violations if you add ad-hoc macros to more than one source files: these must be set the same in every translation unit.


И тут я понял, что с таким подходом нарушение ODR рано или поздно случится. Проект большой, за всеми и всем не уследишь. Я уже однажды ловил нарушение ODR — три недели поисков. Спасибо, больше не надо.
Пришлось всё откатить назад, а код написать "ручками".
Вот так я и не смог округлить float до int...
А вы говорите "ногти". Если бы только это!
И каждый день — без права на ошибку...
Re[2]: Кто нибудь понимает код STL от MS?
От: AndrewJD США  
Дата: 19.09.14 16:27
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>Здравствуйте, Juster, Вы писали:


J>>код STL от MS?


Q>Код STL от Microsoft писался в Dinkumware.


В последних версиях студии STL идет от Microsoft и нормально читается.
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Re: Кто нибудь понимает код STL от MS?
От: omgOnoz  
Дата: 19.09.14 16:39
Оценка:
Здравствуйте, Juster, Вы писали:

J>Я когда туда заглядываю, мне сразу закрыть хочется. Такое ощущение, что код был создан авто-генератором каким-то, форматирование неудобное, имена жутко запутанные, структура довольно сложная. Кто-то в этом разбирается? Я уж про буст не говорю, там пока разберешься во всех typedef, ifdef, все ногти перекусаешь


Писателям бы показать код реализации таких же контейнеров в Java. Или это не лечится?
Отредактировано 19.09.2014 16:40 omgOnoz . Предыдущая версия . Еще …
Отредактировано 19.09.2014 16:39 omgOnoz . Предыдущая версия .
Re[2]: Кто нибудь понимает код STL от MS?
От: smeeld  
Дата: 20.09.14 06:27
Оценка: -2 :))
Здравствуйте, B0FEE664, Вы писали:


BFE>Понять-то можно, но вот то, что писатели (как правило) совершенно не думают о читателях или удобном использовании — это почти всегда так.


Чукча не читатель. А нечукча поймёт любой код, в том числе и дизассемблерный листинг.
На кывте вообще собрались нежинки какие-то: код для них должен быть обязательно без напряга
читаем, и это чуть ли не главный критерий его качества. Вы, товарищи, разрабы или нежные барышни?
ЗЫ хватит опенсорсный код называть говнокодом.
Re[2]: Кто нибудь понимает код STL от MS?
От: flаt  
Дата: 22.09.14 09:43
Оценка: +1
Здравствуйте, Кодт, Вы писали:

К>Это библиотека, идущая вместе с компилятором, и отвечающая двум требованиям:

К>- чтобы компилировалась как можно быстрее (отсюда — короткие имена)
???

K>— чтобы не смешивалась с пользовательскими библиотеками (отсюда — имена в зарезервированном для компилятора формате: _Caps и __doubleunderscore)

А для чего namespace тогда?
Re[3]: Кто нибудь понимает код STL от MS?
От: flаt  
Дата: 22.09.14 09:49
Оценка:
Здравствуйте, smeeld, Вы писали:

S>На кывте вообще собрались нежинки какие-то: код для них должен быть обязательно без напряга

S>читаем, и это чуть ли не главный критерий его качества. Вы, товарищи, разрабы или нежные барышни?
оффтоп: это как на хабре любую статью, в т.ч. техническую, оценивают по критерию "легко читается" :hz:
Re[3]: Кто нибудь понимает код STL от MS?
От: B0FEE664  
Дата: 22.09.14 10:41
Оценка:
Здравствуйте, smeeld, Вы писали:

BFE>>Понять-то можно, но вот то, что писатели (как правило) совершенно не думают о читателях или удобном использовании — это почти всегда так.

S>Чукча не читатель. А нечукча поймёт любой код, в том числе и дизассемблерный листинг.
S>На кывте вообще собрались нежинки какие-то: код для них должен быть обязательно без напряга
S>читаем, и это чуть ли не главный критерий его качества. Вы, товарищи, разрабы или нежные барышни?

Я, товарищ, считаю так: если время на чтение кода превышает время его написания, то и читать не стоит.
В том же boost'е есть и хороший код, например circular_buffer. Всё понятно, всё работает, вплоть до обращений с отрицательным индексом к итераторам ( it[-2] ).

S>ЗЫ хватит опенсорсный код называть говнокодом.

Дык другого в общем доступе нет.
И каждый день — без права на ошибку...
Re[3]: Кто нибудь понимает код STL от MS?
От: Кодт Россия  
Дата: 22.09.14 11:05
Оценка: +1
Здравствуйте, flаt, Вы писали:

K>>— чтобы не смешивалась с пользовательскими библиотеками (отсюда — имена в зарезервированном для компилятора формате: _Caps и __doubleunderscore)

F>А для чего namespace тогда?

Сишным макросам, например, плевать на неймспейсы.
Перекуём баги на фичи!
Re[3]: Кто нибудь понимает код STL от MS?
От: watchmaker  
Дата: 22.09.14 11:13
Оценка:
Здравствуйте, flаt, Вы писали:

F>Здравствуйте, Кодт, Вы писали:


К>>Это библиотека, идущая вместе с компилятором, и отвечающая двум требованиям:

К>>- чтобы компилировалась как можно быстрее (отсюда — короткие имена)
F>???
Ну зависимость скорости от длины идентификаторов всё же есть. Это видно на всяких синтетических тестах, где в файле миллион функций с длинами имён в 10 либо в 100 символов. Более длинный файл банально дольше читать :)
Впрочем, большая часть времени компиляции всё равно тратится не на лексический разбор, так что зависимость от длины идентификаторов не слишком сильная — их же всего-навсего нужно один раз прочитать, сложить в какую-нибудь хеш-таблицу, а дальше оперировать только ссылками, где уже длина не играет такой значительно роли. Собственно, если запустить какой-нибудь компилятор в режиме препроцессинга (например, clang++ -E) и в режиме компилирования (clang++ -c), то абсолютное замедление при использовании более длинных имён будет сравнимо, что как бы свидетельствует, что именно на сам процесс компиляции длина сказывается совсем слабо.

В общем, я бы не рассматривал способ сокращения длины идентификаторов как способ ускорения компиляции пока их длина находится в разумных пределах, а не составляет килобайт на каждое имя.

Да и есть более практичные способы ускорения, так использование precompiled headers для стандартной библиотеки даст куда больше выгоды.

K>>— чтобы не смешивалась с пользовательскими библиотеками (отсюда — имена в зарезервированном для компилятора формате: _Caps и __doubleunderscore)

F>А для чего namespace тогда?
Есть места, где namespace использовать нельзя — внутри классов, например. Если реализации std::map нужен идентификатор для типа или данных, то завернуть его в namespace не получится, а дать ему «нормальное» имя тоже — вдруг это имя совпадёт случайно с пользовательским, если он вдруг, например, отнаследуется от класса (это ведь не запрещено, хотя и не рекомендуется для стандартных контейнеров).
Re[4]: Кто нибудь понимает код STL от MS?
От: flаt  
Дата: 22.09.14 11:36
Оценка:
Здравствуйте, watchmaker, Вы писали:


W>Есть места, где namespace использовать нельзя — внутри классов, например. Если реализации std::map нужен идентификатор для типа или данных, то завернуть его в namespace не получится, а дать ему «нормальное» имя тоже — вдруг это имя совпадёт случайно с пользовательским, если он вдруг, например, отнаследуется от класса (это ведь не запрещено, хотя и не рекомендуется для стандартных контейнеров).

Можно подробнее?

Вот банальный код
template<class _Tp>
class vector
{
public:
  typedef _Tp value_type; // что не так может быть с T, что его меняют на _Tp?

  void push_back(const value_type& __x);  // что не так может быть с x, что его нужно заменять на __x?
};


Про макросы понятно, но если говорить о С++?
Re[5]: Кто нибудь понимает код STL от MS?
От: watchmaker  
Дата: 22.09.14 12:29
Оценка: 12 (1)
Здравствуйте, flаt, Вы писали:

F>Здравствуйте, watchmaker, Вы писали:



W>>Есть места, где namespace использовать нельзя — внутри классов, например. Если реализации std::map нужен идентификатор для типа или данных, то завернуть его в namespace не получится, а дать ему «нормальное» имя тоже — вдруг это имя совпадёт случайно с пользовательским, если он вдруг, например, отнаследуется от класса (это ведь не запрещено, хотя и не рекомендуется для стандартных контейнеров).

F>Можно подробнее?
Да пожалуй я тут слишком преувеличил проблему. Хотя при совпадении имён может компилироваться код, который компилироваться не должен — то есть если stl использует имена с __, а программа не использует, то допустить опечатку, приводящую к ложному совпадению будет сложнее :)

F>Про макросы понятно, но если говорить о С++?

А в C++ макросы никуда не делись. Ну то есть в вышеприведённых двух случаях они вполне являются достаточной причиной не использовать имена T и x.
Re[6]: Кто нибудь понимает код STL от MS?
От: Кодт Россия  
Дата: 22.09.14 13:50
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Да пожалуй я тут слишком преувеличил проблему. Хотя при совпадении имён может компилироваться код, который компилироваться не должен — то есть если stl использует имена с __, а программа не использует, то допустить опечатку, приводящую к ложному совпадению будет сложнее


Не буду сейчас лазить в потроха реального STL, просто покажу на примере, где может аукнуться
namespace std
{
  namespace aux
  {
    template<class It> void insertion_sort(It i, It j) { ..... }
    template<class It> void quick_sort    (It i, It j) { ..... }
  }

  // интерфейсная функция
  template<class It>
  void sort(It i, It j)
  {
    if(distance(i,j) < some_treshold)
      aux::insertion_sort(i,j);
    else
      aux::quick_sort(i,j);
  }
}

Если кто-то кое-где определил для своих нужд
namespace aux // откуда мы знали, что это имя задействовано в STL?
{
  struct bar {...};

  void quick_sort(bar* x, bar* y) // "упорядочим два элемента по-быстрому" - откуда мы знали, что это имя значит что-то иное в std::aux ?
  {
    if(x->key > y->key) { quick_swap(x->key, y->key); quick_swap(x->value, y->value); }
  }
}

чуть выше точки включения #include <algorithm>
то у нас посыплется сортировка std::vector<aux::bar> в релизной сборке.
Перекуём баги на фичи!
Re: Кто нибудь понимает код STL от MS?
От: Pavel Dvorkin Россия  
Дата: 22.09.14 14:58
Оценка: :)
Здравствуйте, Juster, Вы писали:

J>Я когда туда заглядываю, мне сразу закрыть хочется. Такое ощущение, что код был создан авто-генератором каким-то, форматирование неудобное, имена жутко запутанные, структура довольно сложная. Кто-то в этом разбирается?


Компилятор.
With best regards
Pavel Dvorkin
Re[7]: Кто нибудь понимает код STL от MS?
От: B0FEE664  
Дата: 22.09.14 22:29
Оценка:
Здравствуйте, Кодт, Вы писали:

  Скрытый текст
К>
К>namespace aux // откуда мы знали, что это имя задействовано в STL?
К>{
К>  struct bar {...};

К>  void quick_sort(bar* x, bar* y) // "упорядочим два элемента по-быстрому" - откуда мы знали, что это имя значит что-то иное в std::aux ?
К>  {
К>    if(x->key > y->key) { quick_swap(x->key, y->key); quick_swap(x->value, y->value); }
К>  }
К>}
К>


К>Не буду сейчас лазить в потроха реального STL, просто покажу на примере, где может аукнуться

К>
К>namespace std
К>{
К>  namespace aux
К>  {
К>    template<class It> void insertion_sort(It i, It j) { ..... }
К>    template<class It> void quick_sort    (It i, It j) { ..... }
К>  }

К>  // интерфейсная функция
К>  template<class It>
К>  void sort(It i, It j)
К>  {
К>    if(distance(i,j) < some_treshold)
К>      aux::insertion_sort(i,j);
К>    else
К>      aux::quick_sort(i,j);
К>  }
К>}
К>

К>Если кто-то кое-где определил для своих нужд
К>чуть выше точки включения #include <algorithm>
К>то у нас посыплется сортировка std::vector<aux::bar> в релизной сборке.

Да с чего бы ей сыпаться? Да и от сборки как это может зависить?

namespace aux // откуда мы знали, что это имя задействовано в STL?
{
  struct bar {...};

  void quick_sort(bar* x, bar* y) // "упорядочим два элемента по-быстрому" - откуда мы знали, что это имя значит что-то иное в std::aux ?
  {
    if(x->key > y->key) { quick_swap(x->key, y->key); quick_swap(x->value, y->value); }
  }
}

namespace std
{
  namespace aux
  {
    template<class It> void quick_sort    (It i, It j) { ..... }
  }

  // интерфейсная функция
  template<class It>
  void sort(It i, It j)
  {
      aux::quick_sort(i,j); // это однозначно std::aux::quick_sort, так как aux продикларирована до и находится внутри
  }
}



  aux::bar* pA = NULL;
  aux::bar* pB = NULL;
  std::sort(pA, pB); // вызовет std::aux::quick_sort


А вот если сказать:
  using namespace std;
  using namespace std::aux;
  ::aux::bar* pA = NULL;
  ::aux::bar* pB = NULL;
  quick_sort(pA, pB); // вызовет ::aux::quick_sort
  quick_sort(NULL, NULL); // вызовет std::aux::quick_sort

то да, есть некая неожиданность. Но сыпаться —
И каждый день — без права на ошибку...
Re[8]: Кто нибудь понимает код STL от MS?
От: Кодт Россия  
Дата: 23.09.14 08:20
Оценка: 6 (1)
Здравствуйте, B0FEE664, Вы писали:

BFE>Да с чего бы ей сыпаться? Да и от сборки как это может зависить?

BFE>А вот если сказать:

Безо всяких using-хаков
#include <cstdio>

namespace aux {
    struct foo {};
    void quick_sort(foo* f1, foo* f2) { printf("user-defined function\n"); }
}

namespace sss {
    namespace aux {
        template<class T> void quick_sort(T i, T j) { printf("standard quick sort\n"); }
        template<class T> void sort_impl(T i, T j) { quick_sort(i,j); } // мы же, якобы, внутри родного неймспейса, - не квалифицируем имя
    }

    template<class T> void sort(T i, T j) { aux::sort_impl(i,j); } // здесь имя квалифицированное, компилятор ищет в нужном пространстве
}

int main() {
    aux::foo p,q;
    sss::sort(&p, &q); // "user-defined function"
}

Вот тебе, Эндрю Кёниг, и юрьев день!
Перекуём баги на фичи!
Re[9]: Кто нибудь понимает код STL от MS?
От: B0FEE664  
Дата: 23.09.14 08:34
Оценка:
Здравствуйте, Кодт, Вы писали:

BFE>>Да с чего бы ей сыпаться? Да и от сборки как это может зависить?

BFE>>А вот если сказать:
К>Безо всяких using-хаков

Переставим sss и aux местами:
#include <cstdio>

namespace sss {
    namespace aux {
        template<class T> void quick_sort(T i, T j) { printf("standard quick sort\n"); }
        template<class T> void sort_impl(T i, T j) { quick_sort(i,j); } // мы же, якобы, внутри родного неймспейса, - не квалифицируем имя
    }

    template<class T> void sort(T i, T j) { aux::sort_impl(i,j); } // здесь имя квалифицированное, компилятор ищет в нужном пространстве
}

namespace aux {
    struct foo {};
    void quick_sort(foo* f1, foo* f2) { printf("user-defined function\n"); }
}

int main() {
    aux::foo p,q;
    sss::sort(&p, &q); // "user-defined function"
}


Ничего не изменилось. Но поведение интересное, согласен.
И каждый день — без права на ошибку...
Re[10]: Кто нибудь понимает код STL от MS?
От: Кодт Россия  
Дата: 23.09.14 08:50
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Ничего не изменилось. Но поведение интересное, согласен.


Тут надо уточнить. ADL — дело тонкое... Я точно не помню, какие там правила попадания в поле зрения.
Когда поле зрения ограничено — от начала файла до точки использования, а когда — от начала до конца файла.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.