Подскажите название велосипеду (anti-template-bloat)
От: superlexx  
Дата: 02.11.09 21:49
Оценка:
Добрый вечер,

появилась проблема: есть два класса, хранящие константные массивы константного размера (которые приходят из кодогенератора). Делают с ними почти одно и тоже, сейчас делается копипейст кода, нехорошо.
Классический случай -- делаем предка и функции на него перелагаем. Но приходится вручную передавать размеры массива и vtable появляется (чтобы засады себе не делать).
Используем вместо обычного предка template c "non-type template parameter", размером массива, и aggreation вместо derivation. Копипейста нету, но появляется template bloat (то есть bloat уже был, но стал неявным).
Можно добавить ещё один вспомогательный класс и добить врага, но как-то влом. А почему бы не решить так: оставить template + aggregation, но сделать особую специализацию "implementation class".
То есть так:
template<size_t SIZE>
class C
{
    const int (&m_array) [SIZE][SIZE];
    static const size_t s_implementationSize = ~0u;
    static const bool s_isImplementation = (SIZE == s_implementationSize);
    typedef C<s_implementationSize> Implementation;

    template<size_t OTHER_SIZE>
    friend class C;

    static void Do(_In_count_x_(size * size) const int* const array, const size_t size)
    {
        static_assert(s_isImplementation, "implementation-instantiated only");
    }

    C operator=(C);
    C(C&);
    C();

public:

    explicit C (const int (&array)[SIZE][SIZE]) :
      m_array(array) {}

    void Do() const
    {
        static_assert(!s_isImplementation, "must not be implementation-instantiated");
        Implementation::Do(&(m_array[0][0]), SIZE);
    }
};
Всё есть, что надо, и в одном месте. Но такая народная самодеятельность немного стрёмна, очень желаю сослаться на какого-нибудь классика. В интернете все встреченные версии используют наследование. Не подскажите, кто уже писАл такое?

Кстати, можно ограничить friend-statement, чтобы "C<FOO> {friend} C<~0u>", но "C<FOO> {!friend} C<BAR>", где BAR != ~0u ?
template bloat non-template parameter
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.