2011-02-03 7 views
16

は、あなたはよく形成され、プログラムでタイプvoidのインスタンスを持つことができないので、次の宣言のようなものがコンパイルされません。void型::明らかにタプル

std::tuple<void, double, int> tup; 

しかし、としてオブジェクトとは対照的に型を厳密に扱っている限り、問題はないようです。例えば、私のコンパイラ(GCC)は、私が言うことができます:

typedef std::tuple<void, double, int> tuple_type; 

C++ 0xで私達はちょうどそのメタプログラミングのトリックの多くを実行するためにstd::tupleを使用できるようですので、これは、私には興味深いものです以前はboost::mplライブラリが必要でした。たとえば、std::tupleを使用して型のベクトルを作成できます。

たとえば、私たちは関数のシグネチャを表すタイプのベクトルを作成したいとします

私達はちょうど言うことができます:

template <class R, class... Args> 
struct get_function_signature; 

template <class R, class... Args> 
struct get_function_signature<R(*)(Args...)> 
{ 
    typedef std::tuple<R, Args...> type; 
}; 

これは、関数の署名がvoidを持っている場合でも、動作しているようですが実際にはget_function_signature<F>::typeのインスタンスをインスタンス化することはできません。

しかし、C++ 0xはまだ私には新しく、もちろんすべての実装はまだやや実験的なので、これについて少し不安です。メタプログラミングのタイプのベクトルとして実際にstd::tupleを使用できますか?

+1

私は 'boost :: mpl :: vector'が推奨されなくなると考えています。とにかく、boost :: mpl'機能とテンプレートメタプログラミングの大部分は、バリデーショナルテンプレートのサポートが増えるとかなり変化します。 –

答えて

10

それは実際にあなたがいる限り、あなただけでtuple_elementを使用するタイプのリストとしてそれを使用するよう

typedef std::tuple<void, double, int > tuple_type;

を行うことができます意味をなさないありません。したがって、私たちはそれをインスタンス化しない限り、おそらく、void要素とtupleが安全であるvoid*

+0

いくつかの標準的なライブラリの実装では、これを何も問題なくサポートしている他の標準的なライブラリの実装が何年も経ってもこれを処理できないようです。たとえば、ClangがMSVCの標準ライブラリを使用していない限り、GCCとClangはそれを拒否し、MSVCはそれを受け入れます。 –

0

としてのparamを宣言します

tuple_element<0,tuple_type>::type * param;

を行うことができます。我々は

struct C : std::tuple<void> {... 

、以下のように書くことはできませんけれども、この使用法は今有用であることが
だから、私はケースを想像することはできません。 それは問題ではありません。

これはstd::pairにも当てはまります。 我々は、次のような単純なタイプのリストを書くことができます。

struct Nil; 
typedef std::pair< void, std::pair< int, Nil > > t; 

何とか、このようなpair使用量は稀のようですけれども。

ちなみに、tupleタイプリストは、SFINAEのような目的で失敗する可能性があります。 たとえば、次のコードはideone(gcc-4.5)でコンパイルされません。ときに私 がテスト1):

std::tuple<void> f(); 
template< class T > char g(T const&); 

int main() { 
    sizeof g(f()); 
} 

だから、私は現在のタイプのリストは、近い将来に tupleと完全に置き換えることができるということはよく分かりません。

関連する問題