_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)だけですか?
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);
};
既存の回答は素晴らしいものであり、確かに標準化委員会にとってこの目的のために不可欠でした。しかし、私が言及するのに十分重要であると思う別の問題があります。
無料の関数を使用すると、インターフェイスを変更できますなしクラスの定義を変更します。グローバルget
を特殊化するだけで、任意のタイプを「取得可能」にすることができます。メンバー関数では、クラスを直接変更する必要があります。
範囲ベースのfor
は、クラス型のメンバーbegin/end
を検索しますが、ADLを介して非メンバーbegin/end
も検索します。これらのAPIは、begin/end
関数を持たないものでも、任意のコンテナーで使用できます。たとえば、LibXML2要素タイプに特化して、xmlElement*
よりも範囲ベースのfor
を使用できます。
メンバー関数でなければならない場合は、それを行うことはできません。
C++では、フリー関数は、さまざまな種類のクラスで実行できる多くの操作の自然なインターフェースです。
N3090/3092、§20.4.2.6/ 8:「注:getが非メンバー関数である理由は、この機能がメンバー関数として提供されている場合、型がテンプレートパラメーターに依存するコードでは、templateキーワードを使用する必要があるためです。 。—文末脚注