2009-09-24 4 views
24

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

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

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

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

ответ

22

я нашел следующее issue report, который говорит

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

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

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

1

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

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

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

+0

Хорошо, никогда не ум - отчет вопрос, очевидно, лучше, чем моя догадка: P – me22

0

Я видел это требование, тоже. Но.

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

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

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

+0

Кто-то подал проблему и запрос на перенос для [симпатичного принтера] (http://louisdx.github.com/cxx-prettyprint/) однажды, предвидя, что эти дополнительные аргументы действительно появились в их коде MSVC и, таким образом, сделанные специализации, которые я предоставил break ... :-( –

2

Невероятно, но я недавно читал «C++ Шаблоны: Полное руководство», и последняя книга отмечена следующая на странице 111:

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

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

В реальном мире тест, я составил следующий в г ++ (успешно) и 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; 
} 
+2

Что они подразумевают под «аргументами шаблона по умолчанию аргумента шаблона шаблона игнорируются» является то, что даже если параметр может иметь аргумент по умолчанию, этот аргумент по умолчанию не является u sed и соответствующие значения параметров, как если бы у него не было аргумента по умолчанию. Поэтому, если у impl будет вектор с 3 параметрами, а третий имеет аргумент по умолчанию, то передача вектора в качестве аргумента шаблона шаблона будет таким, как если бы этот аргумент по умолчанию отсутствовал. –

+0

Я попытался скомпилировать пример с g ++ 4.4.1 - он отклоняет, а g ++ 4.1 принимает код. Это похоже на ошибку в GCC. –

+0

Спасибо за разъяснение в этом отрывке - я интерпретировал его несколько иначе. Я собрал 4.1 (старая Fedora VM, которую я ногами). – csj

Смежные вопросы