LINUX.ORG.RU

Глубоко в С++


0

0

Давно интересуют два вопросика:

1) Как сравнивать указатели? Часто встречается их сравнение с помощью std::less. Зачем это? Я так и не увидел, чем это лучше простых операторов ><. Просто для красоты?

2) Ключевое слово export. Нигде не могу найти примеров его использования( что не странно, так как оно не поддерживается большинством компиляторов, по крайней мере я таких не видел ) Просто интересно, правильно ли я понял.

в file.h пишем

export template<typename T> void my_template_fn( T t ) {

...

}

и тогда в file.cpp можно сделать так:

#include "file.h"

template<typename T> void my_template_fn( T t );

void f() { T t; my_template_fn( t ); }

я прав?

Ответ на: комментарий от anonymous

>да...

Это ты про что именно. Вопросы с изюмом?

>купи труп страуса и углубись в чтение

Углублялся, и не раз. На первый вопрос ответа не видел. А второе я хочу просто уточнить, правильно ли я его( мертвого страуса) понял.

PS: вообще, разговаривать со страусами, а тем более мертвыми - это шиза.

devinull ★★
() автор топика
Ответ на: комментарий от Selecter

>Как я понял, export можно упускать, т.к. и без него компилятор >распознаёт функции.

Не совсем верно. Даже совсем неверно!
export позволяет указывать в .H файлах только объявление шаблона (класса или функции), а код шаблона записывать в .CPP файл, который компилируется в некий "объектный код".
При этом для использования шаблона в другом исходнике нужно подключать только .H файл с объявлением. Плюс нужно при компиляции дополнительно указать скомпилированный файл с кодом шаблона.
Всё это очень удобно если хочется скрыть от пользователя шаблона детали его реализации.

К сожалению, насколько я знаю, пока ни один C++ компилятор не поддерживает такую возможность.

romanSA
()
Ответ на: комментарий от romanSA

>Всё это очень удобно если хочется скрыть от пользователя шаблона детали его реализации.

Вызывающе неверная информация. Это очень удобно, если хочешь, чтобы время сборки проекта уманьшилось на пару порядков.

devinull ★★
() автор топика

2 devinull :

По п.2 Вы абсолютно правы, но как я уже говорил, эту фичу никто не реализовал.

По п.1:
std::less<> используется для обеспечения сортировки в контейнерах, которые хранят свои данные упорядочено (например std::map<> ).
Этот шаблон использует для сравнения operator < для типа, который указан как параметр шаблона.

Зачем это нужно? Рассмотрим объявление шаблона std::map<> (упрощенно, конечно).

std::map< KeyType, ValueType, Compare = std::less< KeyType > >

Третий параметр шаблона - это объект-функция, используемый для сравнения величин типа KeyType.
Должен быть допустим вызов объекта-функции в виде

bool result = Compare (key1, key2);

При этом функция возвращает true, если key1 "меньше" key2.
К сожалению operator < () не всегда подходит для использования в качестве Compare и вот для этого и был придуман std::less<>.

Почитать об этом можно почти в любой книжке, посвященной STL.



romanSA
()
Ответ на: комментарий от devinull

В реальных задачах (примерно 200 - 300 тыс. строк кода) я особых тормозов при компилляции не видел...
Правда я не собираю KDE, GNOME, GCC и пр. :)

romanSA
()
Ответ на: комментарий от romanSA

>По п.1:

Это всё понятно, но меня смутил код basic_string в несколькоих реализациях:

if( std::less(const value_type*)()( my_buf, str ) )

и т.д.

оно чем-то лучше чем

if( my_buf < str ) )

? я читал "Язык программирования С++", и не раз, но нигде не видел упоминаний об этом. Просто не часто в таких местай вставляют такие "навороты" забавы ради...

Вот о чем я спрашивал. Насчет STL и типичного применения std::less вопров нет.

devinull ★★
() автор топика
Ответ на: комментарий от romanSA

> export позволяет указывать в .H файлах только объявление шаблона (класса или функции), а код шаблона записывать в .CPP файл, который компилируется в некий "объектный код".

Ты такое хоть раз в жизни видел? Я - нет. Как ты себе представляешь объектный код шаблона? Разве что, прекомпиляция в некоторый промежуточный код, но это не есть объектный код.

watashiwa_daredeska ★★★★
()
Ответ на: комментарий от romanSA

Это из-за того, что Вы не сравнивали с компиляторами, поддерживающими export. Если сейчас специализация шаблона нужна в 100 единицах трансляции, то она будет сгенерирована 100 раз. При использовании export её достаточно сгенерировать единажды. Разумеется, это при условии, что во всех этих единицах значения всех лексемм, использованных в определении шаблона одинаково.

devinull ★★
() автор топика
Ответ на: комментарий от watashiwa_daredeska

>Ты такое хоть раз в жизни видел? Я - нет.

Никто этого не видел, потому что это не поддерживается ни одним компилятором. Объектный код шаблона - это бред. А вот в объектном коде специализации шаблона ничего необычного нет. Никто не запрещает линковщику, если тот обнаружит нехватку каких-то специализаций, обратиться к компилятору с просьбой инстанциировать их из кода в определённом файле файле.

devinull ★★
() автор топика
Ответ на: комментарий от watashiwa_daredeska

2 watashiwa_daredeska
Вот я и взял слова "объектный код" в кавычки... :)
Кстати вот вопрос, код батника на Bash это исходник или исполняемый код? ;)

2 devinull
А Вы не подумали, что можно написать специализацию std::less<>, которая не будет вызывать operator < () и будет работать из-за этого быстрее?

По поводу export : быстрая сборка важна, но обычно проект строится так, чтобы не компилировать каждый раз все исходники. А вот если Вы поставляете свою библиотеку на "коммерческой основе", то возможность сокрытия деталей реализации довольно востребована.
Впрочем, это совсем не возражение Вышему видению полезности export.

romanSA
()
Ответ на: комментарий от devinull

> Никто не запрещает линковщику, если тот обнаружит нехватку каких-то специализаций, обратиться к компилятору с просьбой инстанциировать их из кода в определённом файле файле.

Бред. Инстанциирует шаблоны компилятор, когда появляется необходимость. А чтобы инстанциировать, компилятору нужно полное определение шаблона, а не только объявление. Именно поэтому, шаблоны пишутся целиком в заголовочных файлах и смысла (да и возможности) разделять объявление и определение нет.

Линковщик же, никакие компиляторы уже не вызывает, ибо это бред. Он всего лишь собирает готовое в одну кучу.

watashiwa_daredeska ★★★★
()
Ответ на: комментарий от devinull

> Если сейчас специализация шаблона нужна в 100 единицах трансляции, то она будет сгенерирована 100 раз. При использовании export её достаточно сгенерировать единажды.

На это придумали precompiled headers.

watashiwa_daredeska ★★★★
()
Ответ на: комментарий от romanSA

>А Вы не подумали, что можно написать специализацию std::less<>, которая не будет вызывать operator < () и будет работать из-за этого быстрее?

Для указателей? Сами понимаете...

Насчет сокрытие кода - согласен. Но Страуструп утверждает, что видел проекты время сборки которы сокращалось "с нескольких часов до такого же количества минут" из-за одной лишь более грамотной организации инстанциирования шаблонов. Там речь шла в основном о явном инстанциировании нужных специализаций наиболее често используемых шаблонов.

devinull ★★
() автор топика
Ответ на: комментарий от watashiwa_daredeska

Линковщик должен обратиться к компилятору, сказать ему, что нужно инстанциировать такую-то специализацию такого-то шаблона, _определенного_ в таком-то файле. Это не бред, это С++ ;)) Забавно, но многие люди преподающие С++ про это ни разу не слышали. ;))) Но в стандарте это есть. Читай стандарт и свежие труды Страуструпа. Если смелости хватит ;))

devinull ★★
() автор топика
Ответ на: комментарий от watashiwa_daredeska

>На это придумали precompiled headers

Только не в стандарте.

devinull ★★
() автор топика
Ответ на: комментарий от devinull

> Линковщик должен обратиться к компилятору, сказать ему, что нужно инстанциировать такую-то специализацию такого-то шаблона, _определенного_ в таком-то файле.

Нет. Линковщик линкует готовый объектный код. Он ничего не знает про шаблоны, определения шаблонов, их инстанциацию и, честно говоря, про C++ вообще. Он знает формат объектного файла, а кем, из чего и как этот объектный файл был сделан, линковщику глубоко фиолетово. Можно с таким же успехом делать точно такие же объектные файлы, например, из исходников на Pascal. Или сочинить собственный язычок.

Именно поэтому, линковщик никаких компиляторов вызывать не должен. Компилятор на то и компилятор, чтобы сгенерить объектный код для всего, что нужно, _до_ вызова линковщика.

> Это не бред, это С++

Так что, это всё-таки бред.

> Но в стандарте это есть.

Что, в стандарте на C++ решили явно указать, что C++ нужен собственный линковщик, несовместимый ни с какими другими? Ну-ну...

watashiwa_daredeska ★★★★
()
Ответ на: комментарий от watashiwa_daredeska

>Именно поэтому, линковщик никаких компиляторов вызывать не должен

Не "не должен", а "не обязан". Это может делать какая-то другая програмка, которая будет разгребать ошибки линковки.

Так что, все-таки не бред ;)

PS: ты почитай умные книжки сначала, а уж потом рассуждай.

devinull ★★
() автор топика

Только что ошибку заметил, имелось ввиду:

в file1.cpp пишем

export template<typename T>

void my_template_fn( T t ) { ... }

в file2.cpp можно сделать так:

template<typename T> void my_template_fn( T t );

void f()

{

T t;

my_template_fn( t );

}

devinull ★★
() автор топика
Ответ на: комментарий от devinull

Sorry for english. std::less is preferred over operator<(sometype,sometype) because std::less is well defined, while operator< may be redefined by the user. Recall that template code is instantiated in scope of user definitions: this means, btw, that if I define some weird character type, and some weird operator< for the char typein near nampespace, than the compiler will use the operator< for comparison.

std::less, however, is always the same.

omerm
()
Ответ на: комментарий от omerm

Прошу прощения за русский. ;) Да, об этом я не подумал. Совершенно согласен. Спасибо.

devinull ★★
() автор топика
Ответ на: комментарий от execve

Огромнейшая благодатность за ссылку! Наконец-то нашел пример. Да и одного крикуна тут в лужу посадили... ;)

devinull ★★
() автор топика
Ответ на: комментарий от devinull

>Вызывающе неверная информация. Это очень удобно, если хочешь, чтобы время сборки проекта уманьшилось на пару порядков.

Вызывающе неверная информация. 1) Механизм export не реализован. 2) В единственном компиляторе, в котором реализован, уменьшения времени сборки afaik также не происходит.

Прочити главу про export в книжке herb sutter'а (на русском называется "новые сложные задачи на c++", не знаю как в оригинале).

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.