Частичный typedef

В прошлой заметке я показал, как сделать аллокатор для stl контейнеров, но использовать это в сыром виде нереально, ибо такой код сломает руки и глаза. Попытаемся исправить ситуацию. Сырой вид:

typedef std::vector<int, StlAllocator<int, HEAP_STL_CONTAINERS_TAG> > TVec;  
TVec vec;  
vec.push_back(30);  

Первое что приходит на ум - написать typedef для типа вектора с нашим аллокатором, но компилятор это не переварит :)

// логично, но неверно
template < typename T >  
typedef std::vector<T, StlAllocator<T, HEAP_STL_CONTAINERS_TAG> > vector;  

Читаем документацию, стандарт, форумы, и понимаем, что такого в плюсАх просто нет. Окей, придется что-то придумывать. Из головы приходит сразу два решения:

1) наследоваться от вектора и определить аллокатор, аля:

template < typename T >  
class vector : public std::vector<T, StlAllocator<T, HEAP_STL_CONTAINERS_TAG> > {  
    /// ...
};

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

2) сделать всё это через внешнюю структуру, а там уже сделать typedef, костыльно, конечно, но что ж поделать.

// наш "чудо-костыль"
namespace bm {  
    template < typename T, typename A = StlAllocator<T, HEAP_STL_CONTAINERS_TAG> >
    struct vector {
        // сам тип вектора
        typedef std::vector<T,A> type;

        // а это для удобства получения типов итераторов,
        // когда не делаешь своего typedef'а на конкретный тип вектора
        typedef typename type::iterator       iterator;
        typedef typename type::const_iterator const_iterator;
    };
}

// пример использования

void foo() {  
    bm::vector<int>::type my_vec;
    my_vec.push_back(1);
}

Конечно, лишний ::type режет глаз, но на это придется пойти и ждать поддержки С++11 везде, об этом ниже.

P.S.
В новом стандарте осознали проблему с typedef'ами и ввели решение в стандарт. Выглядит оно так:

template < typename T >  
using vector = std::vector<T, StlAllocator<T, HEAP_STL_CONTAINERS_TAG>>;

void foo() {  
    vector<int> my_vec;
    my_vec.push_back(1);
}

Отлично, но... поддержки-то пока везде нет, на данный момент, например, нет поддержки "Type aliases" (как комитет назвал его), в последней версии Visual Studio. Поэтому те, кому нужна кросскомпиляторность, вынуждены использовать костыли описанные выше и ждать :(