можно ли установить значение по умолчанию для std::tr1::tuple?

(я использую Visual C++ 2010) предположим, что я определил такой кортеж:

typedef std::tr1::tuple<
int      //i want to set its default value to 9
, double //i want to set its default value to 3.3
, int    //i want to set its default value to 2
, double //i want to set its default value to -7.2
> Mytuple; 

я могу сделать это в структуре. но мне интересно, возможно ли это сделать в std::tr1::tuple.
Кроме того, я хочу знать, когда мне следует использовать std::tr1:tuple или struct?

кто-нибудь может мне помочь?


person Triumphant    schedule 09.11.2012    source источник
comment
Мой общий совет — избегать кортежей. За исключением надуманных примеров, они значительно усложняют чтение кода ради экономии нескольких строк в заголовочном файле.   -  person cdhowie    schedule 09.11.2012
comment
Если это требование вашего типа, создайте новый тип.   -  person GManNickG    schedule 09.11.2012
comment
К вашему сведению: если вы используете VS2010, вы не должны не использовать std::tr1::tuple. Вы должны использовать std::tuple (даже если это псевдоним using из пространства имен tr1, он может быть не позже. И ваш код будет совместим с миром не VS).   -  person Nicol Bolas    schedule 09.11.2012
comment
tuple не следует использовать, если вы знаете количество полей. Используйте его только для вариативных вещей.   -  person Dani    schedule 09.11.2012
comment
@Dani: я не мог не согласиться. Даже функциональные языки, в которых кортежи являются абсолютно основной, базовой структурой данных, не поддерживают сопоставление с вариативным шаблоном для кортежей. Кортежи следует использовать, когда для написания нового правильного типа будет просто больше кода, чем оно того стоит (например, очень локализованный код).   -  person ildjarn    schedule 09.11.2012
comment
@Dani На самом деле, для некоторых небольших внутренних контейнеров простых значений я иногда предпочитаю это, поскольку отказ MSVC автоматически генерировать элементы перемещения может быть очень раздражающим для таких простых структур.   -  person Christian Rau    schedule 09.11.2012
comment
Несмотря на то, что stdlib != STL, tuple не имеет ровно ничего общего с STL (например: вызов vector STL может быть приемлемым в некоторых ситуациях, потому что это было в STL. tuple не было).   -  person Griwes    schedule 10.11.2012


Ответы (1)


tuple не является волшебной заменой структуры. Их цели очень разные. Структура — это прежде всего языковая конструкция. tuple — это библиотека.

Структуры должны иметь значения по умолчанию, потому что язык говорит, что вы можете написать конструкторы, чтобы дать им значения по умолчанию. Затем язык берет на себя ответственность за вызов этого конструктора для инициализации структуры. tuple, как библиотека, не имеет таких возможностей, так же как вы не можете задать std::vector<T> значение по умолчанию T, которое всегда будет автоматически использоваться. Вы можете указать начальные значения для каждого члена, но не можете указать значения по умолчанию.

А если подумать, то и не захочется. Представьте, если бы кто-то мог сказать, что каждый tuple<int, float> всегда создавался с помощью 3 и 54.221. Даже если бы его создал какой-то другой код, который ничего не знал об этом правиле, ему нужно было бы следовать (точно так же, как конструкторы для типа используются везде, где используется этот тип). Помните: все tuple<int, float> относятся к одному типу.

На самом деле, tuple заменяет невозможность выполнения отражения структуры и выполнения итераций во время компиляции по ее членам. Другая основная причина, по которой они существуют, заключается в том, чтобы иметь возможность иметь динамические структуры времени компиляции (то есть возможность создавать агрегаты типов на основе аргументов времени компиляции, а не статический список, записанный непосредственно в файл).

Поэтому, если вам не нужно использовать std::tie (для эффективного возврата нескольких значений), итерации по членам (т.е.: вызывать некоторую функцию шаблона для каждого члена объекта) или какой-то аналогичный специализированный код, вы должны использовать структуру.

person Nicol Bolas    schedule 09.11.2012
comment
@Xeo: Что такое кусочная конструкция? - person Nicol Bolas; 09.11.2012
comment
@NicolBolas, где я могу узнать об использовании tuple для выполнения итерации во время компиляции над членами класса и динамическими структурами во время компиляции? - person Seth Carnegie; 09.11.2012
comment
@Seth: вы можете сделать первое только косвенно, если класс предоставляет свои члены как кортеж, а для второго подумайте, что bind нужно сделать для хранения связанных аргументов. NicolBolas: Примером может быть std::pairs, преобразующий два параметра ctor. Если вы передаете кортежи, они напрямую перенаправляются в сохраненные типы. Если вы передадите std::piecewise_construct в качестве дополнительного первого параметра, вы получите содержимое кортежей, переданных типам. - person Xeo; 09.11.2012
comment
@Xeo: это фактически расширение невозможности перебирать элементы структуры. Вы используете кортеж для хранения параметра, а не структуру только потому, что вы можете эффективно распаковать кортежи в параметры для конструкторов. Вы не можете сделать это со структурами из-за отсутствия отражения во время компиляции. - person Nicol Bolas; 09.11.2012
comment
Еще одно практическое использование (например, оно работает на практике, но не гарантируется в теории), которое у меня есть для кортежей, — это контейнер EBCO-in-a-package, потому что по крайней мере реализации libc++ и libstdc++ дать вам это (не знаю о MSVC, но я надеюсь, что это тоже), то есть они оптимизируют хранилище, необходимое для пустых членов кортежей. - person R. Martinho Fernandes; 10.11.2012