std::tuple функция-член get()

boost::tuple имеет функцию-член get(), используемую следующим образом:

tuple<int, string, string> t(5, "foo", "bar");
cout << t.get<1>();  // outputs "foo"

Кажется, что C++0x std::tuple не имеет этой функции-члена, и вместо этого вы должны использовать форму функции, не являющейся членом:

std::get<1>(t);

что для меня выглядит более уродливым.

Есть ли какая-то конкретная причина, по которой std::tuple не имеет функции-члена? Или это только моя реализация (GCC 4.4)?


person HighCommander4    schedule 22.07.2010    source источник
comment
Как правило, предпочтение отдается функциям, не являющимся членами.   -  person GManNickG    schedule 23.07.2010


Ответы (3)


Из черновика С++ 0x:

[Примечание. Причина, по которой get не является функцией-членом, заключается в том, что если бы эта функциональность была предоставлена ​​как функция-член, код, в котором тип зависел бы от параметра шаблона, потребовал бы использования ключевого слова шаблона. — примечание в конце]

Это можно проиллюстрировать с помощью этого кода:

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);
};
person doublep    schedule 22.07.2010
comment
Я понимаю. Тем не менее, они могли бы предоставить как функции-члены, так и функции, не являющиеся членами, такие как boost, хотя бы по какой-либо другой причине, которая была бы совместима с boost (поскольку многие люди, вероятно, уже использовали кортежи boost до перехода на C++0x). . - person HighCommander4; 23.07.2010
comment
@HighCommander4 Хотя я понимаю ваш аргумент, одна только повышенная совместимость не является достаточной причиной сама по себе, поскольку совместимость с существующими решениями не должна быть единственной движущей силой для предоставления чего-либо в новом стандарте, и даже повышение не является не-плюс-ультра и может выиграть от некоторого пересмотра. Сказав эти общие слова, я по-прежнему согласен с тем, что Member-gets было бы хорошей идеей. - person Christian Rau; 16.10.2012
comment
Теперь, когда у нас есть С++ 11, который больше не требует ключевого слова шаблона, мы можем теперь полностью иметь функцию-член? Просто нужно предложение? - person texasbruce; 13.12.2018

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

С бесплатными функциями у вас есть возможность изменять интерфейс без изменения определения класса. Вы можете сделать любой тип «доступным», просто настроив глобальный файл get. С функцией-членом вам придется напрямую изменить класс.

for на основе диапазона ищет член begin/end в типах классов, но он также ищет begin/end, не являющийся членом, через ADL. Эти API можно использовать с любым контейнером, даже с тем, у которого нет begin/end функций. Вы можете специализировать его, например, для типов элементов LibXML2, чтобы вы могли использовать диапазон for вместо xmlElement*.

Вы не можете сделать это, если они должны быть функциями-членами.

В C++ свободные функции являются естественным интерфейсом для многих операций, которые можно выполнять с различными типами классов.

person Nicol Bolas    schedule 16.10.2012
comment
std::begin/std::end также являются хорошими примерами того, как функции-члены и функции, не являющиеся членами, могут прекрасно работать вместе. Вы можете использовать любой из них с большинством контейнеров. - person jakar; 13.05.2014

N3090/3092, §20.4.2.6/8: «Примечание. Причина, по которой get не является функцией-членом, заключается в том, что если бы эта функциональность была предоставлена ​​как функция-член, код, в котором тип зависел бы от параметра шаблона, потребовал бы использования ключевого слова шаблона. . —конец примечания"

person Jerry Coffin    schedule 22.07.2010