Функция std:: tuple get()
boost::tuple
имеет функцию-член get()
, используемую следующим образом:
tuple<int, string, string> t(5, "foo", "bar");
cout << t.get<1>(); // outputs "foo"
Кажется, что С++ 0x std::tuple
не имеет этой функции-члена, и вместо этого вы должны использовать не-членную форму:
std::get<1>(t);
который для меня выглядит более уродливым.
Есть ли какая-то особая причина, почему std::tuple
не имеет функции-члена? Или это только моя реализация (GCC 4.4)?
Ответы
Ответ 1
Из С++ 0x черновик:
[Примечание. Причина get is notmember - это то, что если эта функция была предоставлена как функция-член, код, в котором тип, зависящий от параметра шаблона, потребовался бы с использованием ключевого слова template. - конечная нота]
Это можно проиллюстрировать с помощью этого кода:
template <typename T>
struct test
{
T value;
template <int ignored>
T& member_get ()
{ return value; }
};
template <int ignored, typename T>
T& free_get (test <T>& x)
{ return x.value; }
template <typename T>
void
bar ()
{
test <T> x;
x.template member_get <0> (); // template is required here
free_get <0> (x);
};
Ответ 2
Существующие ответы велики и, безусловно, для комитета по стандартам были жизненно важны для этой цели. Но есть еще одна проблема, которая, по моему мнению, достаточно важна, чтобы упомянуть.
С бесплатными функциями у вас есть возможность изменять интерфейс без изменения определения класса. Вы можете сделать любой тип "gettable" просто, специализируясь на глобальном get
. С помощью функции-члена вам нужно будет непосредственно изменить класс.
Это одна из причин того, что основанный на диапазоне for
построен на std::begin/std::end
вместо поиска функций-членов. std::begin/end
специализированы для типов массивов, поэтому вы можете использовать for
на основе диапазона с массивами. Вы можете использовать его с любым контейнером, даже с теми, у которых нет функций begin/end
. Вы можете специализировать его, например, для типов элементов LibXML2, так что вы можете использовать for
на основе диапазона xmlElement*
.
Вы не можете этого сделать, если они должны быть функциями-членами.
В С++ свободные функции являются естественным интерфейсом для многих операций, которые могут выполняться для разных классов.
Ответ 3
N3090/3092, §20.4.2.6/8: "Примечание: причина get - это функция, отличная от того, что если эта функция была предоставлена как функция-член, код, в котором тип зависел от параметра шаблона, потребовал бы использования ключевое слово шаблона. -end note"