Компиляция специализации шаблонов C ++ - PullRequest
3 голосов
/ 20 июля 2010

Я собираюсь описать мою проблему подробно, чтобы объяснить, чего я пытаюсь достичь, вопрос в последнем параграфе, если вы хотите игнорировать детали моей проблемы.

У меня естьпроблема с дизайном класса, в которой я хочу передать значение любого типа в функции push() и pop(), которые преобразуют переданное значение в строковое представление, которое будет добавлено к строке внутри класса, эффективно создавая потокданных.Обратное произойдет для pop(), взяв поток и преобразовав несколько байтов в начале потока обратно в указанный тип.

Создание шаблонов push() и pop(), связанных с stringstream, являетсяочевидное решение.Однако я хочу использовать эту функцию внутри DLL, в которой я могу изменить способ хранения строки (например, шифрование или сжатие) без перекомпиляции клиентов.Шаблон типа T необходимо будет перекомпилировать при изменении алгоритма.

Моя следующая идея состояла в том, чтобы просто использовать такие функции, как pushByte(), pushInt(), popByte(), popInt() и т. Д.Это позволило бы мне изменить реализацию без перекомпиляции клиентов, поскольку они полагаются только на статический интерфейс.Это было бы хорошо.Тем не менее, это не так гибко.Например, если значение было изменено с байта на короткое, все экземпляры pushByte (), соответствующие этому значению, нужно было бы изменить на pushShort(), аналогично для popByte() на popShort().Перегрузка pop() и push() для борьбы с этим может привести к конфликтам в типах (вызывая явное приведение, которое в конечном итоге приведет к той же самой проблеме).

С вышеупомянутыми идеями я мог бы создать рабочий класс.Однако мне было интересно, как компилируются специализированные шаблоны.Если бы я создал push<byte>() и push<short>(), это была бы перегрузка, зависящая от типа, и переход от байта к короткому автоматически переключал бы используемый шаблон, что было бы идеально.

Теперь мой вопрос таков:если бы я использовал специализированные шаблоны только для имитации этого вида перегрузки (без шаблона типа T), все ли специализации компилировались бы в мою DLL, позволяя мне отправлять новую реализацию без перекомпиляции клиента?Или специализированные шаблоны выбираются или отбрасываются таким же образом, как шаблон типа T во время компиляции клиента?

Ответы [ 2 ]

2 голосов
/ 20 июля 2010

Прежде всего, вы не можете просто иметь специализированные шаблоны без базового шаблона для специализации.Это просто запрещено.Вы должны начать с шаблона, а затем предоставить его специализации.

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

Я бы, вероятно, просто использовал перегрузку.Проблема, о которой я думаю, вы говорите, возникает с чем-то порядка:

int a;
byte b;

a = pop();
b = pop();

Где вы просто перегрузите pop на тип возвращаемого значения (который, как и все мызнаете, не допускается).Я бы избежал этого довольно просто - вместо того, чтобы возвращать значение, передайте ссылку на значение, которое нужно изменить:

int a;
byte b;

pop(a);
pop(b);

Это не только позволяет работать с разрешением перегрузки, но по крайней мере для меня выглядит чище, так какхорошо (хотя, может быть, я только что написал слишком много ассемблера, поэтому я привык к таким вещам, как «топор»).

1 голос
/ 20 июля 2010

Звучит так, как будто у вас есть 2 противоположных фактора:

  1. Вы хотите, чтобы ваши клиенты могли нажимать / вставлять / и т.д.каждый числовой тип.Шаблоны кажутся естественным решением, но это противоречит согласованной (нужно компилировать только один раз) реализации.
  2. Вы не хотите, чтобы ваши клиенты перекомпилировали при изменении аспектов реализации. идиома pimpl выглядит как естественное решение, но это противоречит общей (работающей с любым типом) реализации.о числовых типах, а не произвольных ТВы можете объявить специализации вашего шаблона для каждой из них в явном виде в файле заголовка и определить их в исходном файле, и клиенты будут использовать определенные вами специализации, а не компилировать свои собственные.Специализации являются формой полиморфизма времени компиляции.Теперь вы можете комбинировать его с полиморфизмом во время выполнения - реализуйте специализации в терминах класса реализации, который не зависит от типа.Ваш класс реализации может использовать boost :: variable , чтобы сделать это, поскольку вы заранее знаете диапазон возможных значений T (boost::variant<int, short, long, ...>).Если повышение не подходит для вас, вы можете придумать подобную схему самостоятельно, если у вас есть конечное число Ts, о которых вы заботитесь.
...