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

Функция 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)?

4b9b3361

Ответ 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"