7


3

実行時にクラスのジェネリック型を選択する方法はありますか、それともCではコンパイル時のものですか。

私がやりたいことはこのようなものです(擬似コード):

ジェネリック型if(somveval == 1)type = Integer; if(someval == 2)type = String。

list myList;

これはCで可能ですか? そしてもしそうなら、どうですか?

5 Answer


11


コンパイル時のことです。 テンプレートパラメータの型はコンパイル時にコンパイラに認識されなければなりません。

つまり、特定のテンプレートメタプログラミング手法を使用して、コンパイル時にすべての可能な型がわかっている場合、および型を選択するための条件が解決できる場合に限り、1つの型または別のATコンパイル時を選択できます。コンパイル時に。

たとえば、部分特殊化を使用すると、整数に基づいてコンパイル時に型を選択できます。

テンプレートクラスFoo {};

テンプレート構造体select_type;

template <> struct select_type <1> {typedef int型; ;

template <> struct select_type <2> {typedef float型; ;

int main(){Foo :: type> f1;} // Foo Foo :: type> f2を返します。 //あなたにFooを渡します}


2


Boost.Variant(固定数の異なる型)またはBoost.Any(任意の型を格納できる型、基本的には「voidポインタ」だが型情報付き)で可能です。

StringとIntegerがたまたま多態的な基本クラスから派生している場合もあります。 (ただし、そのためには、同じインターフェイスを実装する必要があります。これは、あなたのケースでは可能かもしれないし不可能かもしれません)。

一般的に、多態性はそれを実行する最も簡単な方法であり、これは確かに常に使用されています。

VariantとAnyは、使用するにはかなりの作業が必要です。それでも、それらが格納している正しいタイプとしてコンテンツを取得するには、まだ何らかの方法で必要です。 (多態的なメソッド呼び出しに頼るのではなく、派生クラスへのダウンキャストを使用する場合と同じようにソートします。)


1


他の人も答えたように、あなたの質問に対する答えは "いいえ"です。Cは実行時に動的な型付けをサポートしません。 私は、あなたが達成しようとしていることによっては、* union *を使用してこの動的な型付けを_単純化することができるかもしれないことを指摘したいと思いました。 library / ms221627.aspx [VARIANT型]はCOMに実装されています。


0


これが役に立つ状況は考えられませんが…

#include "boost / variant.hpp" #include #include

boost :: variant、std :: list> unknown(int someval){if(someval == 1)が返される場合:boost :: variant、std :: list>(std :: list());そうでなければ(someval == 2)がboost :: variantを返すならば、std :: list>(std :: list()); }


0


一番近いものは次のとおりです。

template void do_stuff_with_list {list myList; ... }

列挙型{整数= 1、文字列}。

void do_stuff(Type type){switch(type){case整数:do_stuff_with_list();ブレーク; case String:do_stuff_with_list();ブレーク; ; }