Страница 2 из 2
Re: Как лучше создать версию шаблонной функции?
Добавлено: 26 ноя 2015, 15:41
Romeo
Сионист писал(а):Тот самый случай. Только не из библиотеки. И получаем мультипальную дефиницию. Спасибо.
Это ты получаешь... Возьми уже, и прочти, как работают шаблоны в С++. Почему ты всё время пытаешь во всём разбираться наскоком, идя по граблям и падая в ямы, вместо того, чтобы просто прочесть для начала теорию?
Re: Как лучше создать версию шаблонной функции?
Добавлено: 26 ноя 2015, 15:42
Absurd
только для данного списка типов.
Тот самый случай.
Это мудизм. Правильность типа надо проверять примерно так:
Код: Выделить всё
template<typename Q> struct AbilityToStoreTest {
enum {
value =
std::is_same<Q, MXUOcta>::value
| std::is_same<Q, MXUTetra>::value
| std::is_same<Q, MXUWyde>::value
| std::is_same<Q, MXUByte>::value
| std::is_same<Q, MXSOcta>::value
| std::is_same<Q, MXSTetra>::value
| std::is_same<Q, MXSWyde>::value
| std::is_same<Q, MXSByte>::value
| std::is_same<Q, MXFp>::value
| std::is_same<Q, MXFps>::value
};
};
/* ..... */
template<typename R> void storeMem(MXUOcta base, MXUOcta offset, R val)
{
static_assert(ExecutionContextPrivate::AbilityToStoreTest<R>::value, "Illegal type for storeMem");
*mapAddress<R>(base, offset) = val;
}
Re: Как лучше создать версию шаблонной функции?
Добавлено: 26 ноя 2015, 16:13
Сионист
Не правильно, ты хотел сказать. Если все эти окты с тетрами - расход памяти, то long int смешается с float, а double будет отдельно от float, а надо все действительные вместе, а целые отдельно. Кроме того, wcharf_t тоже двухбайтный, и будет смешан с short int, а должен быть с нечисловыми. А если это конкретные типы, то такие типы мне нафиг не нужны.
Re: Как лучше создать версию шаблонной функции?
Добавлено: 26 ноя 2015, 16:16
Romeo
Absurd писал(а):Правильность типа надо проверять примерно так
Да, для данного случая такой проверки вполне достаточно, так как здесь всё расположено внутри одного проекта. Более того, ограничение на список типов и не нужно, просто
Сионист намудрил.
Absurd писал(а):Это мудизм.
Не совсем так. Механизм явного инстанцирования нужен на стыке библиотек. Если мы выставим наружу из нашей библиотеки хедер вместе с телом, то тем самым откроем третье стороне внутреннее представление нашей функции/класса. Более того, это внутреннее представление скорее всего потянет за собой зависимости, которые третьей стороне совсем не нужны. Если же мы спрячем тело внутрь cpp (который третье стороне поставлен не будет), то увеличим модульную инкапсуляцию кода, уменьшим связность, а так же легко избежим вот таких хитрых проверок типов просто за счёт того, что сгенерируем разрешённые экземпляры с помощью явного инстанцирования внутри cpp файла, для прочих же типов запрет будет работать очень просто, ведь код просто не слинкуется. Именно для такого случая в 11 стандарте был введён синтаксис явного инстанцирования и синтаксис указания внешней линковки шаблонных функций/классов.
Re: Как лучше создать версию шаблонной функции?
Добавлено: 26 ноя 2015, 16:46
Absurd
Не правильно, ты хотел сказать.
Фигасе самомнение какое. Это
мой код. Я им решаю
свою проблему, связанную с тем что шаблон mapAddress<> весьма нетривиален, и если там указать рандомный тип он развернется в непонятную хренотень. Поэтому я отсекаю все возможности которые я не предусмотрел. И да, у меня все типы хранятся в одной памяти, там union{ }.
Кстати, можно и разнести по разным банкам памяти. Там есть такой шаблон
Код: Выделить всё
class ExecutionContext {
/* ... */
template <typename R> struct TypeSwitch {
static R* locCache(ExecutionContext&);
};
template <typename R> friend struct TypeSwitch;
/* ... */
};
/* ... */
template<typename R> inline void ExecutionContext::storeReg(MXUByte reg, R val)
{
static_assert(ExecutionContextPrivate::AbilityToStoreRegTest<R>::value, "Invalid type for storeReg");
ExecutionContext::TypeSwitch<R>::locCache(*this)[reg] = val;
}
TypeSwitch частично специализируется для всех возможных типов:
Код: Выделить всё
template<> inline MXUOcta* ExecutionContext::TypeSwitch<MXUOcta>::locCache(ExecutionContext& ctx)
{
return ctx.rcache_.uReg_;
}
template<> inline MXSOcta* ExecutionContext::TypeSwitch<MXSOcta>::locCache(ExecutionContext& ctx)
{
return ctx.rcache_.sReg_;
}
template<> inline MXFp* ExecutionContext::TypeSwitch<MXFp>::locCache(ExecutionContext& ctx)
{
return ctx.rcache_.fpReg_;
}
При этом ctx.rcache_ это union. Если ее заменить на структуру, то все будет разнесено по разным банкам памяти. Но мне это не надо.
Union используется вместо конверсии указателей чтобы не ломать aliasing rules, иначе в gcc c -O3 это работать не будет.
Кроме того, wcharf_t тоже двухбайтный, и будет смешан с short int
Там где-то в настройках проекта есть опция - трактовать wchar_t как независимый тип либо же как typedef для short.
Re: Как лучше создать версию шаблонной функции?
Добавлено: 26 ноя 2015, 17:14
WinMain
Здесь проблема возможно кроется не в реализации шаблона как такового, а в банальном оформлении заголовочного файла.
Заголовочный файл должен выглядеть примерно так...
Код cpp:
#ifndef _YOURHEADERNAME_
#define _YOURHEADERNAME_
// TODO: содержимое заголовочного файла...
#endif // конец файла
Такой подход предотвращает множественное определение одних и тех же сущностей
Re: Как лучше создать версию шаблонной функции?
Добавлено: 26 ноя 2015, 17:41
Absurd
Механизм явного инстанцирования нужен на стыке библиотек.
Я вообще противник того чтобы темплейты гонять через библиотеки. Если лениво создавать extern "C" интерфейс лучше не заморачиваться и предоставлять библиотеку в виде набора .h файлов. Либо не использовать шаблоны. Да и сейчас вообще концепция бинарных библиотек ИМХО выходит из моды. Поменял какую-то dll-ку и часть программ сломалась. Язык Go не умеел создавать библиотеки, когда я на него в последний раз смотрел. Не думаю что это недосмотр.
Re: Как лучше создать версию шаблонной функции?
Добавлено: 26 ноя 2015, 19:58
Сионист
WinMain писал(а):Здесь проблема возможно кроется не в реализации шаблона как такового, а в банальном оформлении заголовочного файла.
Заголовочный файл должен выглядеть примерно так...
Код cpp:
#ifndef _YOURHEADERNAME_
#define _YOURHEADERNAME_
// TODO: содержимое заголовочного файла...
#endif // конец файла
Такой подход предотвращает множественное определение одних и тех же сущностей
Именно так и выглядят все 12 штук.
Re: Как лучше создать версию шаблонной функции?
Добавлено: 26 ноя 2015, 19:59
Сионист
Absurd писал(а): Поменял какую-то dll-ку и часть программ сломалась.
Не сломалась, так будет правильней.
Re: Как лучше создать версию шаблонной функции?
Добавлено: 26 ноя 2015, 21:44
Absurd
Сионист писал(а):Не сломалась, так будет правильней.
Это не тебе вообще. Ты там вообще выше по треду озадачился работоспособностью программы под Спектрумом. 20-ти летний студент Спектрум бы не упомянул. Мимо. 30-ти летний дядя который сидит в кожаном кресле старшего программиста, имеет жену, любовницу, сертификат системного программиста от MS, пару золотых и дюжину серебряных медалей на stackoverflow и при этом не может написать простой шаблон и не умеет пользоваться гуглом - тоже мимо.