3

C++ はほとんどが C のスーパーセットですが、常にそうとは限りません。特に、C と C++ の両方の列挙値は暗黙的に int に変換されますが、その逆は当てはまりません。C でのみ int が列挙値に変換されます。したがって、列挙型宣言を介して定義されたビットフラグは正しく機能しません。したがって、これは C では問題ありませんが、C++ では問題ありません。

typedef enum Foo
{
    Foo_First = 1<<0,
    Foo_Second = 1<<1,
} Foo;

int main(void)
{
    Foo x = Foo_First | Foo_Second; // error in C++
    return 0;
}

この問題を効率的かつ正しく、理想的には Foo を変数の型として使用するデバッガー フレンドリーな性質を損なうことなく (ウォッチなどのコンポーネントのビットフラグに分解する)、どのように処理する必要がありますか?

また、そのようなフラグの列挙が何百もあり、ユースポイントが何千もある可能性があることも考慮してください。理想的には、ある種の効率的な演算子のオーバーロードでうまくいくでしょうが、実際には効率的であるべきです。私が考えているアプリケーションは、コンピューティング バウンドであり、高速であるという評判があります。

明確化: 大規模な (>300K) C プログラムを C++ に変換しているので、実行時と開発時の両方で効率的な変換を探しています。適切なすべての場所にキャストを挿入するだけでも、数週間かかる場合があります。

4

3 に答える 3

8

結果を Foo にキャストしないのはなぜですか?

Foo x = Foo(Foo_First | Foo_Second);

編集: この質問に最初に回答したとき、問題の範囲がわかりませんでした。上記は、いくつかのスポット修正を行うために機能します。あなたがしたいことのために、 | を定義する必要があります。2 つの Foo 引数を取り、Foo を返す演算子:

Foo operator|(Foo a, Foo b)
{
    return Foo(int(a) | int(b));
}

int キャストは、望ましくない再帰を防ぐためにあります。

于 2008-10-14T00:49:43.483 に答える
2

キャストの理想的なアプリケーションのように思えます.はい、ランダムな整数で Foo をインスタンス化することを意図していることをコンパイラに伝えるのはあなた次第です.

もちろん、技術的に言えば、Foo_First | Foo_Second は Foo の有効な値ではありません。

于 2008-10-14T00:50:46.147 に答える
0

結果を int または static_cast のままにします。

Foo x = static_cast<Foo>(Foo_First | Foo_Second); // not an error in C++
于 2008-10-14T00:49:51.283 に答える