-1

varargs コンテキストでスコープ付き列挙型を使用する場合、「列挙型クラス値を varargs 関数の引数として使用できますか?」で回答されているように、基になる型として渡されるように定義されています。スコープ付き列挙型は、スコープなし列挙型のように暗黙的に変換されます。

このプログラムを考えてみましょう:

enum Foo : char { F };
enum class Bar : char { B };

#include <cstdio>
int main()
{
    return !std::printf("%c\n", Foo::F)
        +  !std::printf("%c\n", Bar::B);
}

コンパイラ (g++バージョン 6.3.0) は、 a の最初の出力に満足していますが、 aFooを渡すと不平を言いBarます:

0.cpp: In function ‘int main()’:
0.cpp:10:34: warning: format ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘Bar’ [-Wformat=]
         +  !printf("%c\n", Bar::B);
                                  ^

g++バージョン 4.8.2 ではこれについて不満はありませんでしたが、g++6.3.0 では問題がありました (それが今私が懸念している理由です)。%forを使用するなどの実質的な不一致がある場合、または基になる型を使用する%sように変更した場合、両方のバージョンが最初の印刷について文句を言います。それが私が有効にする理由です。Foolong-Wformat

警告は標準準拠の問題ではないことを理解しており、これらに対処するためにコードを変更する方法を知っています (たとえば、How can I output the value of an enum class in C++11?への回答で関数を使用します)。また、誤検知が発生する場合、警告は役に立たないと思います。列挙型の基になる型がフォーマット文字列の対応する変換仕様と一致する場合、スコープ付き列挙型をフォーマットされた I/O 関数に渡すと、実際に害が及ぶ可能性はありますか?

4

1 に答える 1