Dumitru
всем привет)
у меня опять магия с шаблонами
// A.h
class A{
public:
template<class T>
static Message get_message();
void random_func();
};
// A.cpp
template<class T>
Message A::get_message() { return T(); }
void A::random_func() { get_message<MsgA>(); }
//B.cpp
void B::some_func()
{
get_message<MsgB>();
}
проблема в том что у меня компилятор не видет функцию для MsgB, если я использую MsgB в классе A все ок
я так понимаю это из-за того что у меня все файлы компилируються отдельно и когда очередь доходит до B он то для него просто нет этой функции
подскажет кто как это исправить ?
Dumitru
MsgA и MsgB наследуются от Message
Anonymous
A::get_message
Dumitru
ой, забыл дописать, оно там есть
A::get_message
Ned
Мне тут недавно сказали, все шаблоны в один хедер, чтобы компилилось ровно
Andrey
Andrey
туда A заинклюжен?
Dumitru
да, везде стоит include
Dumitru
Dumitru
он класс находит, не нахожит конкретно реализацию метода
Dumitru
причем если в А вызывать <MsgB> то в B не будет проблем
Dumitru
Dumitru
можно просто сдуру вызвать функцию в А, но это некрасиво
да и она блокирующая
Anonymous
Может фигню скажу, но попробуй B наследовать от A
Andrey
Anonymous
попробуй определение статической шаблонной функци A::get_message в хедер вынести
Dumitru
Dumitru
определение шаблонов надо писать в хэдере ?
я просто раньше не очень их использовал
Anonymous
да
Dumitru
сейчас попробуем
Anonymous
шаблон генерит функцию на этапе компиляции (если она используется)
Anonymous
т.е. в файле B никто не знает о том как определена функция, ее нет
Andrey
не, это порушит все :D
🙈 порушит уже все то, что у тебя статик в А потом нахера ты ее юзаешь в B, архитектура какая-то странноватая )
Алдар
Anonymous
а зачем в http сервере static get_message?
Kirill
Как же меня забавляет эта обфускация при запросе помощи :)
Andrey
Anonymous
реюзабль кот!
Dumitru
у меня ж сервер тоже получает сообщения
когда к нему обращаються
Kirill
Клиент и сервер не должны взаимодействовать друг с другом в одном приложении.
Andrey
в общем я бы архитектуру пересмотрел бы. static - это вообще общий метод, ну если примитивно рассматривать. Чего ты его в неймспейс просто не засунешь? Если нет зависимостей от сервера и клиента?
Kirill
В смысле классов.
Dumitru
Kirill
Однажды ты узнаешь про идиому Pimpl и будет вообще шикарно. :)
Dumitru
Поставил в namespace и все заработало, почему я раньше об этом не подумал...
Всем спасибо!
Anonymous
даешь god-классы!1
Dumitru
Andrey
Dumitru
Kirill
Общее правило: если функция, работающая с классом, не требует доступа к его внутренним полям, или этот доступ эффективно осуществим через геттеры/сеттеры, то функцию лучше объявить следом за классом в том же файле в том же простанстве имен. Исключение: шаблонные классы.
Andrey
Kirill
Класс std::string пример неудачного проектирования. :)
Kirill
В нем больше сотни функций-членов.
Andrey
stl в первоначальном виде, это отдельная песня
Kirill
Из которых 2/3 можно сделать внешними.
Andrey
Степанов в принципе не любит ООП )
Kirill
Какой Степанов?
Dumitru
А на сколько хорошая практика реализовывать функции в хэдере ?
Anonymous
Andrey
отравившись рыбой :D
Kirill
а чем стринг плох?
Anonymous
Dumitru
Алдар
есть еще такая штука - anonymous namespace
Алдар
тарить в ней реализацию всяких хелперов
Anonymous
да, точно
Andrey
для инлайнов есть
inline
Kirill
для инлайнов есть
inline
но если нет lto и оно в другой единце трансляции, то пофиг на инлайн, из одного бьекта в другой ничего не перескочит
Andrey
Andrey
Kirill
В среднестатистическом коде после оптимизации функции, объявленные как встроенные, не будут встроены, а многие из не объявленных встроятся. :)
Kirill
я по специфике работы пишу на O3 и смотрю асм листинги
Kirill
вот там такой пипец, когда все параметры шаблонно передаются компилятору на откуп дается сквозная оптимизация))
Kirill
Сочувствую.
Kirill
Что бы там Линус не говорил про i386, его ассемблер это жесть.