Параметры шаблона по умолчанию с прямым объявлением

StackOverflow https://stackoverflow.com/questions/1792253

Вопрос

Можно ли перенаправить объявление класса, который использует аргументы по умолчанию, не указывая и не зная этих аргументов?

Например, я хотел бы объявить boost::ptr_list< TYPE > в классе признаков без перетаскивания всей библиотеки Boost в каждый файл, содержащий эти признаки.Я хотел бы заявить namespace boost { template<class T> class ptr_list< T >; }, но это не работает, потому что это не совсем соответствует истинному объявлению класса:

template < class T,
    class CloneAllocator = heap_clone_allocator,
    class Allocator = std::allocator<void*>
    >
class ptr_list { ... };

Есть ли у меня варианты только смириться с этим или указать boost::ptr_list< TYPE, boost::heap_clone_allocator, std::allocator<void*> в моем классе черт характера?(Если я использую последнее, мне также придется переслать объявление boost::heap_clone_allocator и включать в себя <memory>, Я полагаю.)

Я просмотрел книгу Страуструпа, SO и весь остальной интернет и не нашел решения.Обычно люди обеспокоены тем, что не включают STL, и решение таково: "просто включите заголовки STL". Однако Boost - это гораздо более массивная библиотека, требующая больших затрат компилятора, поэтому я бы предпочел не использовать ее, если только в этом нет крайней необходимости.

Это было полезно?

Решение

Любой модуль компиляции, который использует ваше средство, которое переадресовывает данные boost, должен будет в любом случае включать заголовки boost, за исключением случая, когда у вас есть определенные программы, которые фактически не будут использовать часть boost вашего средства.

Это правда, что путем прямого объявления вы можете избежать включения заголовков boost для таких программ.Но вам придется вручную включить заголовки boost (или иметь #ifdef) для тех программ, которые на самом деле используют часть boost.

Имейте в виду, что в будущем выпуске Boost могут быть добавлены дополнительные параметры шаблона по умолчанию.Я бы не советовал использовать этот маршрут.Что я бы посоветовал, если вашей целью является ускорение компиляции, так это использовать #define чтобы указать, следует ли отключить код, использующий эту библиотеку boost.Таким образом, вы избежите проблем с прямым объявлением.

Другие советы

ДА.Аргументы шаблона по умолчанию могут быть указаны в любое время и в любом месте, при условии, что объявления не конфликтуют друг с другом.В конечном счете они объединяются вместе из различных деклараций.

Даже это законно:

template< class A, class B, class C = long >
class X;

template< class A, class B = int, class C >
class X;

template< class A = short, class B, class C >
class X { };

Аналогичный пример приведен в §14.1/10.Согласно этому параграфу, аргументы функции по умолчанию ведут себя аналогично.

Удачи в том, чтобы заставить forward declaration вести себя прилично и не блевать на все подряд!

Я не думаю, что вы можете переадресовать объявление шаблона с аргументами по умолчанию, если только соответствующая библиотека не предоставила свой собственный заголовок переадресации объявления.Это связано с тем, что вы не можете повторно использовать аргументы по умолчанию (даже если они совпадают...gcc по-прежнему будет сообщать об “ошибке:переопределение аргумента по умолчанию”).

Итак, насколько мне известно, решение заключается в том, чтобы библиотека предоставила заголовок прямого объявления Foo_fwd.h:

#ifndef INCLUDED_Foo_fwd_h_
#define INCLUDED_Foo_fwd_h_
template<class T, class U=char> class Foo; // default U=char up here
#endif

и тогда полная реализация в Foo.h была бы:

#ifndef INCLUDED_Foo_h_
#define INCLUDED_Foo_h_
#include "Foo_fwd.h"
template<class T, class U> class Foo { /*...*/ }; // note no U=char here
#endif

Итак, теперь ваш код также может использовать Foo_fwd.h ...но, к сожалению, поскольку этот подход требует изменения исходного Foo.h для удаления аргументов по умолчанию, это не масштабируется до сторонних библиотек.Может быть, нам следует лоббировать команду C ++ 0x, чтобы разрешить эквивалентное соответствие аргументов шаблона по умолчанию, а-ля typedefs ...?

Ну и здесь та же проблема.Но с STL.

Если один из моих заголовков использует, например.std:: vector тогда я должен включить весь заголовок целиком.С этого времени каждый раз, когда я включаю свой заголовок, даже если мой исходный код вообще не ссылается на std::vector, заголовок включается вместе с моим заголовком.Если вы включите этот заголовок в большое количество мест, это будет означать много избыточного анализа.

Поэтому я переадресовал объявленный std::vector и использовал std :: vector *, но мой код не хочет компилироваться из-за аргументов по умолчанию.Если я помещаю аргументы по умолчанию в свой заголовок, то компилятор отказывается компилировать заголовок stl из-за соответствия аргумента по умолчанию.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top