2017-02-15 5 views
2

私は基礎となるデータタイプに応じて異なるコードを実行しています。 EG:すべてのプリミティブ型に数値を割り当てる標準Cヘッダファイルはありますか?

void *some_data = obtain_data(); 
int data_type = obtain_data_type(); 
switch(data_type) 
{ 
    case CHAR: 
     handle_char(some_data); 
     break; 
    case SHORT: 
     handle_short(some_data); 
     break; 
    case INT: 
     handle_int(some_data); 
     break; 
    // etc... 
} 

私はCHAR、SHORTに数値を代入する列挙型や定数を必要とするこれが機能するためには、INTなどEG:

enum POD_TYPES 
{ 
    CHAR = 1, 
    SHORT = 2, 
    INT = 3 
    // etc. 
} 

は "私自身のローリング" されますここには自明ですが、これを達成するためのより確立された方法であるべきであるようです。これらの値が既にどこかで定義されている標準の(または少なくとも一般的に利用可能な)ヘッダーファイルがありますか?私はcppreferenceにライブラリの見出しに記載されているものは見ていません。 inttypes.hは近いと思われますが、さらに検討すると、これらの型はすべて、整数のシステム固有の最小値/最大値をキャストまたは決定するために使用されるマクロです。

+4

簡潔に - いいえ、標準C. –

+0

に私は疑問ので、ここではdownvotedされていないと仮定しています非常に基本的ですか?私も同意するだろう!それにもかかわらず、私は興味があり、今私たちは知っています。あなたはすべてあなたの魔法使いの帽子をかぶって、今あなたの塔の頂に戻って不平を言うことができます。 ;) –

答えて

4

このような標準定数はありません。あなたは標準化されると思うだろうが、そうではないと思うことがたくさんある。サイドノートとして


、あなたはC11 _Genericキーワードを使用し、多型の振る舞いを実装する代わりに、このような列挙型の実行時のチェックを使用してもう少し現代的なCプログラミングに向けた最初のステップを取ることができます。実際には、あなたが完全に列挙を取り除くことができます。

// variant.h/variant.c 
#include <stdio.h> 

typedef void print_func_t (const void* data); 

typedef struct 
{ 
    void* data; 
    print_func_t* print; 
} variant_t; 


void print_char (const void* data) { printf("%c", *(const char*) data); } 
void print_short (const void* data) { printf("%hd", *(const short*) data); } 
void print_int (const void* data) { printf("%d", *(const int*) data); } 

void print (const variant_t* var) 
{ 
    var->print(var->data); 
} 

#define variant_init(var) { \ 
    .data = &var, \ 
    .print = _Generic((var), char: print_char, short: print_short, int: print_int) \ 
} 

発信者:

int main() 
{ 
    char c = 'A'; 
    short s = 3; 
    int i = 5; 

    variant_t var[3] = 
    { 
    variant_init(c), 
    variant_init(s), 
    variant_init(i) 
    }; 

    for(size_t i=0; i<3; i++) 
    { 
    print(&var[i]); 
    printf(" "); 
    } 

    return 0; 
} 
+0

私の場合、スイッチの代わりに関数ポインタを利用する方がはるかに洗練された解決策でした。インスピレーションをありがとう! –

+0

@Groo隣接する数字の大文字と小文字のスイッチは、ほとんどの場合、関数ポインタの配列に対して内部的に最適化されます。どちらの場合も、その部分は抽象レイヤーの背後に隠れています。多形の任意の形式は、関数ポインタテーブルの何らかの方法として終わる。私はこれがコードをより保守不能にする方法に従わず、またどこから '何か 'を得ることも理解していません。また、このソリューション全体では、関数呼び出しのオーバーヘッドを考慮しても、分岐を少なくしてパフォーマンスを向上させる必要があります。 – Lundin

+0

@ Lundin:心配しないで、私は初めてよく答えを読まなかった。 – Groo

0

これはC++のバリアント型と呼ばれます。そこのようなあなたのためにこれを行うに多くのライブラリ、以下のとおりです。

  1. QVariant

Boost any

  • Qtの
  • からは、しかし、そのようなライブラリを使用する際に支払うべき代償があることを覚えておいてください。バリアントを使用すると効率的ではありませんが、OPC/UAプロトコルを使用する場合など、必要なときがあります。

    +0

    皮肉なことに、私が取り組んでいるプロジェクトは、以前はC++の本格的なQtアプリケーションでした。私は自分自身がQt/C++の機能に強く拘束され、制約に遭遇した後、Cの最初から始めました。それは過度の反応かもしれません。 –

    +1

    @AlexJohnson私は主にGUIのためにQtを使用しています。それ以外は、私はブーストやその他に依存しています。あなたの場合、Boost :: anyを使うことができます。 )(Qtと違って)非常に平和なライセンスもあります。実際にあなたがGoogleの "variant type for C"の場合、他の多くのライブラリを見つけることができます。 –

    +0

    関連:http://stackoverflow.com/questions/2734808/variant-datatype-library-for-c –

    関連する問題