ページ 1 / 1
マクロ関数について
Posted: 2012年6月22日(金) 11:58
by cn
はじめまして。cnと申します。
現在マクロ関数の定義の方法について悩んでいます。
次のような定義があったとき、
コード:
/* code 1*/
#define Get(n,type) ((type) n)
typedef unsigned int my_u_int
typedef signed int my_s_int
typedef float my_float
Get関数を次のように呼びたいです。
コード:
/* code 2 */
#define GetType(i) ((i==0) ? my_u_int : ((i==1) ? my_s_int : my_float))
int main() {
int t=0;
/* tが変化 */
double g = Get(123.456,GetType(t));
return 0;
}
非常にややこしいですが、やりたいことは次のとおりです。
・code1の定義は絶対に変更できない
・変数tの結果によってGet関数の第2引数を {my_u_int, my_s_int, my_float}のいずれかにする(tは0~2の間であると仮定する)←これをマクロ化したい
そこで登場したのがcode2のGetType関数です。
しかし、これではコンパイルが通りません。(当たり前ですが)
コード:
error: expected expression before ‘my_u_int’
error: expected ‘)’ before numeric constant
このような感じにコードを(なるべくスマートに)書こうとしたらどのように書けば良いのでしょうか?
Re: マクロ関数について
Posted: 2012年6月22日(金) 12:18
by softya(ソフト屋)
マクロは関数ではありません。
なので動的に変化する変数とコンパイル時に確定するのもの(マクロ)を同義に扱ってもうまくいくことはありません。
そもそも、こんな変換をしたい意図を教えて下さい。
あとC++は使っても良いのでしょうか?
Re: マクロ関数について
Posted: 2012年6月22日(金) 12:22
by YuO
C/C++において,型は静的に決まらないといけません。
故に,実行時の値によって型を切り替えることはできません。
各型用のコードを用意して,switch等で呼び出しをかえることになります。
# templateで共通化できる可能性もあります。
Re: マクロ関数について
Posted: 2012年6月22日(金) 12:42
by cn
softyaさん、YuOさんご回答ありがとうございます。
>そもそも、こんな変換をしたい意図を教えて下さい。
今現在とあるライブラリを用いているのですが、そのライブラリでcode1のようにtypedef struct(今後これをTYPEと呼びます。)されています。
TYPEはa={signed, unsigned, float} b={4, 8, 16, 32, 64}の二つの条件から成り立っています(実際は9個)。
プログラム内で
コード:
if (aa==signed && bb==4} {...} else if {aa==unsigned && bb==4} {...} ...
[/codel
のように毎回条件分岐を書くのがとても億劫に感じていたから、GetType関数のようにできらた楽かなと考えたからです。
>あとC++は使っても良いのでしょうか?
g++4.5.2でコンパイルできるなら問題ありません。
># templateで共通化できる可能性もあります。[/quote]
簡単にでも教えていただけると助かります。
Re: マクロ関数について
Posted: 2012年6月22日(金) 12:46
by cn
☓今現在とあるライブラリを用いているのですが、そのライブラリでcode1のようにtypedef struct(今後これをTYPEと呼びます。)されています。
○今現在とあるライブラリを用いているのですが、そのライブラリでcode1のようにtypedef(今後これをTYPEと呼びます。)されています。
Re: マクロ関数について
Posted: 2012年6月22日(金) 21:29
by ookami
こんにちは、ookamiです。
自信ないですが
#define GetType(i,v) ((i==0) ? Get(v,my_u_int) : ((i==1) ? Get(v,my_s_int) : Get(v,my_float)))
:
:
double g=GetType(t,123.456)
という感じでしょうか?
この場合は型変換の警告が出ると思いますが...
利用シーンがよく分からない...^^;
Re: マクロ関数について
Posted: 2012年6月22日(金) 21:55
by softya(ソフト屋)
すいません出かけていて返答が遅くなりました。
ookamiさんのでOKだと思いますが私も必要性を感じません。
Re: マクロ関数について
Posted: 2012年6月22日(金) 22:39
by cn
ookamiさん、softyaさんご回答ありがとうございます。
まず説明不足であったことの謝罪をさせてください。
申し訳ありませんでした。
いわゆる画像ライブラリで、1ピクセルあたりの型を指定できます。
それが{signed, unsigned, float} {4, 8, 16, 32, 64}です。
画像用構造体にはこの情報が含まれています。
また、このライブラリではTYPEを引数にした関数がたくさんあります。
例えば画素値を取得するには
コード:
valus = Get (image, x, y, plane, TYPE)
のような関数が存在します。
このとき、TYPEを動的に変えたいと考えています。
本来ならば
コード:
if (signed && 4) then {
values = Get (image, x, y, plane, s_char)
} else if (unsigned && 4) then {
values = Get (image, x, y, plane, u_char)
} else if (....)
...
..
.
とするべきなのですが、引数としてTYPEを使う関数が多く、
すべての関数でこのような分岐を書かなければならず、簡潔に書けないかと考えていました。
そこで、マクロを使えば
コード:
values = Get (image, x, y, plane, MACRO(val))
のように一行で書けるのではないかと考えた次第です。
>ookamiさん
なるほど。Getをラップするような形にすればできますね。
マクロ定義自体は長くなりますが、とても簡潔です。
一度この手法で実装を行ってみようと思います。
ありがとうございます。
(そもそも根本的に考え方?が不適切かもしれません・・・)