5

次のコードを有効にしてコンパイルしようとしgccましC++11た。

unsigned int id = 100;
unsigned char array[] = { id % 3, id % 5 };

次の警告が表示されます。

{ } 内の '(id % 3u)' の 'unsigned int' から 'unsigned char' へのナローイング変換 [-Wnarrowing]

オンラインでデモを見る

id %3の結果がunsigned charに収まることをコンパイラが見つけられるようにする方法はありますか?

4

4 に答える 4

9

この特定のケースでは、id constまたはconstexprを作成すると問題が解決します。

constexpr unsigned int id = 100;

変換後の結果がターゲット型に収まる定数式がある場合には例外があるためです。

より一般的なケースでは、static_castを使用して結果を unsigned char にキャストすることもできます。

{ static_cast<unsigned char>( id % 3), static_cast<unsigned char>( id % 5) }
  ^^^^^^^^^^^                          ^^^^^^^^^^^

ドラフト C++ 標準セクションリストの初期化で、定数式と縮小変換の例外を見つけることができます。8.5.4

縮小変換は暗黙の変換です

次の箇条書きを含めます(強調鉱山):

  • 整数型またはスコープのない列挙型から、元の型のすべての値を表すことができない整数型

欠陥レポート 1449により、文言が元のドラフト C++11 標準から上記で引用したものに変更されたことに注意してください。

于 2014-11-17T14:29:01.690 に答える
3

ほとんどすべての数学演算が引数を に変換するのは、C++ の癖ですint

非拡大%mod%演算子のスケッチを次に示します。

template<class T, class U,class=void> struct smallest{using type=T;};
template<class T, class U>
struct smallest<T,U,std::enable_if_t<(sizeof(T)>sizeof(U))>>{using type=U;};
template<class T,class U>using smallest_t=typename smallest<T,U>::type;

constexpr struct mod_t {} mod;
template<class LHS>struct half_mod { LHS lhs; };
template<class LHS>
constexpr half_mod<std::decay_t<LHS>> operator%( LHS&& lhs, mod_t ) { return {std::forward<LHS>(lhs)}; }
template<class LHS, class RHS>
constexpr smallest_t<LHS, std::decay_t<RHS>> operator%( half_mod<LHS>&& lhs, RHS&& rhs ) {
  return std::move(lhs.lhs) % std::forward<RHS>(rhs);
}

a mod b の結果は、2 つのタイプのうち最小のものになる必要があります。これより大きくなることはありません。おそらく、署名済み/未署名用にいくつかの作業を行う必要がありますが、パントして最初のものを取得します。

id %mod% 3で終わるchar

于 2014-11-17T15:00:48.903 に答える
2

以下を使用できます。

unsigned char array[] = {
    static_cast<unsigned char>(id % 3),
    static_cast<unsigned char>(id % 5)
};
于 2014-11-17T14:23:57.463 に答える
2

と同様idunsigned int、 の型id % 3も になりますunsigned int

コンパイラは、unsigned char(標準では 8 ビット)小さすぎてunsigned int(標準では少なくとも 16 ビット) を受け取ることができない可能性があることを警告します。

もちろん、この特定の例についてはよく知っています。static_cast<unsigned char>(id % ...)縮小変換が安全であることをコンパイラに伝えるために使用します。

于 2014-11-17T14:28:00.377 に答える