std :: tuple get()成员函数

时间:2010-07-22 21:06:09

标签: c++ boost c++11 tuples

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)?

3 个答案:

答案 0 :(得分:62)

来自C ++ 0x草案:

  

[注意:get是一个非成员函数的原因是,如果此功能是作为成员函数提供的,那么使用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);
};

答案 1 :(得分:27)

现有的答案很棒,而且标准委员会当然对此至关重要。但是我认为还有另一个问题很重要。

使用免费功能,您可以修改接口,而无需更改类的定义。您可以通过专门化全局get来制作任何类型的“gettable”。使用成员函数,您必须直接修改类。

基于范围的for在类类型上查找成员begin/end,但它也通过ADL查找非成员begin/end。这些API可以与任何容器一起使用,即使那些没有begin/end功能的容器也可以使用。例如,您可以将它专门用于LibXML2元素类型,这样您就可以基于范围for而不是xmlElement*

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

在C ++中,自由函数是许多操作的自然界面,可以在许多不同类上完成。

答案 2 :(得分:12)

N3090 / 3092,§20.4.2.6/ 8:“注意:get是非成员函数的原因是,如果此功能是作为成员函数提供的,那么依赖于模板参数的类型需要使用的代码模板关键字。-end note“