C++ std::tuple get()成员函数

C++ std::tuple get()成员函数,c++,boost,c++11,tuples,C++,Boost,C++11,Tuples,boost::tuple有一个get()成员函数,如下所示: tuple<int, string, string> t(5, "foo", "bar"); cout << t.get<1>(); // outputs "foo" 在我看来更难看 std::tuple没有成员函数有什么特殊原因吗?或者它只是我的实现(GCC 4.4)?

boost::tuple
有一个
get()
成员函数,如下所示:

tuple<int, string, string> t(5, "foo", "bar");
cout << t.get<1>();  // outputs "foo"
在我看来更难看

std::tuple
没有成员函数有什么特殊原因吗?或者它只是我的实现(GCC 4.4)?

来自C++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);
};
模板
结构测试
{
T值;
模板
T&U成员获取()
{返回值;}
};
模板
T&free\u get(测试和x)
{返回x.value;}
模板
无效的
条()
{
测试x;
x、 模板成员_get();//此处需要模板
免费获得(x);
};

现有的答案非常好,当然,对于标准委员会来说,这是至关重要的。但我认为还有一个问题非常重要,值得一提

使用自由函数,您可以在不更改类定义的情况下修改接口。只需专门化全局
get
,就可以使任何类型成为“gettable”。对于成员函数,您必须直接修改该类

基于范围的
for
在类类型上查找成员
begin/end
,但它也通过ADL查找非成员
begin/end
。这些API可以用于任何容器,即使是那些没有
begin/end
函数的容器。例如,您可以将其专门化为LibXML2元素类型,这样您就可以在
xmlement*
的基础上为
指定范围

如果它们必须是成员函数,则不能这样做


<>在C++中,自由函数是许多不同类型的类可以完成的许多操作的自然接口。尽管如此,他们本可以同时提供成员函数和非成员函数,比如boost,如果没有其他原因与boost兼容的话(因为很多人在切换到C++0x之前可能已经使用过boost元组)。@HighCommander4,而我理解你的论点,boost兼容性本身并不是一个充分的理由,因为与现有解决方案的兼容性不应该是在新标准中提供某些内容的唯一驱动力,甚至boost也不是非plus ultra,可能会从某些修订中获益。说了这些话,我仍然同意成员-
get
s是个好主意。现在我们有了不再需要模板关键字的C++11,我们现在完全可以有一个成员函数了?只需要一个建议?作为一个经验法则,非成员函数无论如何都是首选。
std::begin/std::end
也是成员函数和非成员函数可以很好地协同工作的好例子。您可以在大多数容器中使用这两种方法。
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);
};