El problema de tomar un coontainer de biblioteca std existente y compilar con excepciones deshabilitadas es que las interfaces del contenedor std asumen que las excepciones están habilitadas. Usando excepciones, el operador nuevo lanzará si no puede adquirir memoria, sin excepciones, el operador nuevo devuelve un 0 en su lugar, que los contenedores estándar no pueden manejar.
Un enfoque es utilizar únicamente algoritmos STL + vector. Puede replicar aproximadamente el 95% de lo que hacen los otros contenedores al usar esto. El problema es que la mayoría de las implementaciones STL asumen que
v.reserve(v.size()+1);
assert(v.size()+1<=v.capacity());
nunca valer (ya que la reserva se lance si no hay memoria). Para asegurar que esto nunca ocurra, he usado contenedores de "capacidad fija", es decir, contenedores con una capacidad fija en tiempo de compilación. Básicamente, estos son vectores donde paso en un asignador especial. Luego puede verificar max_size() del contenedor antes de la inserción. Entonces solo evita usar cosas como at(). Para una predicabilidad aún mejor, use basic_string en lugar de vector. Esto te obliga a almacenar solo tipos de POD, que nunca se arrojan cuando se copian o se construyen por defecto. Además, los requisitos de memoria son más fáciles de calcular.
Otro enfoque es utilizar contenedores intrusivos. Estos no arrojan (aparte del mal uso de la interfaz), ya que nunca adquieren memoria en primer lugar.