Подтвердить что ты не робот

Контейнеры стандартной библиотеки с дополнительными параметрами шаблона?

Прочитав заявку несколько раз в статьях - я хочу добавить этот вопрос в Stackoverflow и спросить сообщество - это следующий код переносимый?

template<template<typename T, typename Alloc> class C>
void f() {
  /* some code goes here ... */
}

int main() {
  f<std::vector>();
}

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

4b9b3361

Ответ 1

Я нашел следующий отчет , в котором говорится

Нет двусмысленности; стандарт ясен, как написано. Разработчикам библиотек не разрешается добавлять параметры шаблона в стандартные классы библиотек. Это не подпадает под правило "как будто", поэтому оно будет разрешено только в том случае, если стандарт дал явную лицензию разработчикам для этого. Это потребует изменения стандарта.

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

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

Ответ 2

Невероятно, я недавно читал "С++ Templates: The Complete Guide", а последняя книга отмечена на странице 111:

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

Итак, если книга верят, ваш пример, когда нестандартные параметры по умолчанию добавляются в std::vector, будет легальным - поскольку аргументы шаблона шаблона шаблона шаблона по умолчанию игнорируются.

Как настоящий тест, я скомпилировал следующее в g++ (успешно) и Visual Studio 2008 (не удалось выполнить несоответствующие параметры):

template<typename T1, typename T2, typename T3 = float>
class MyClass
{
public:
    T1 v1;
    T2 v2;
    T3 v3;
};

template<template<typename T1, typename T2> class C>
void f()
{
    C<int,double> *c = new C<int,double>();
}

int main ()
{
    f<MyClass>();
    return 0;
}

Ответ 3

Проверьте подпункты 17.4.4 [lib.conforming].

17.4.4.3/3 говорит, что "глобальная или нечлена-функция не может быть объявлена ​​реализацией как принятие дополнительных аргументов по умолчанию", но 17.4.4.4/2 явно позволяет заменять описанные подписи функций-членов длинными, пока дополнительные параметры имеют значения по умолчанию.

Однако нет шаблонов для шаблонов, поэтому, если они считают необходимым предоставить 17.4.4.3/3, мне кажется, что дополнительные параметры шаблона допускают запрет на формулировку обратного.

Ответ 4

Я тоже видел это утверждение. Но.

Во-первых, я никогда не видел реализации, выполняющей это. Я, кажется, помню, что Андрей Александреску однажды рассмотрел использование таких вещей, как типы распределителей на стероидах (что-то вроде my_fancy_thing<std::allocator,more_info_to_pass_to_the_container>, а просто std::allocator все равно будет работать). Но даже это все равно будет поддерживать ваш f(), и что самое близкое к реализации, нарушающему ваш пример, я когда-либо слышал, что обсуждался.

Я думаю, что это в значительной степени относится к той же категории, что и требование о том, что указатель 0 необязательно должен быть представлен значением со всеми битами, установленными в ноль, даже если у продавцов действительно есть такая свобода (что я не знаю, поскольку есть претензии обеих сторон тоже), они никогда не будут использовать его, потому что это сломает практически весь существующий код.

Поэтому я давно решил не беспокоиться об этом.