次の宣言のうち、標準的で好ましいものはどれですか?
int x = 7;
また
int x(7);
int x(7);
C で変数を宣言および初期化する有効な方法ではありません。
C を学ぶための良い本を手に入れ、良いコンパイラを使うことをお勧めします。
c 種類の言語では、通常 int x = 7; を使用します。
この質問に C と C++ の両方のタグを付けましたが、答えは実際には 2 つの場合と同じではありません。
Cでは、int x(7);
単に機能しません。コンパイルさえしません。この形式は C ではまったく機能しないため、推奨される形式はint x = 7;
です。
C++ では動作しますが、この形式は「最も厄介な解析」int x(7);
につながる可能性があるため、注意が必要です。括弧内にあるものを値ではなく型として解釈できる場合、これは、括弧内に指定された値でan を定義するのではなく、an を返すという名前の関数を宣言するものとして解析されます。同様に、括弧を空のままにしておくと、関数宣言になります。x
int
int
int x();
C++ には別の形式があります: int x{7};
. これを「ユニバーサル初期化」と呼ぶ人もいます。それはあいまいさを取り除きます - T id { x };
where T
is a type must be a definition of a id
with x
an initializer. ただし、これを嫌う人もいます。これは、多少異なるセマンティクスが導入されるためです。たとえば、この場合、「ナローイング」変換は禁止されているため、既存のコードをやみくもに変更して新しいフォームを使用することはできません。例えば:
int x(12.34); // no problem
int y{ 12.34 }; // won't compile -- double -> int is a narrowing conversion
これは、上で示したようにリテラルで特に発生する可能性は高くありませんが、次のようなものです。
void f(double x) {
int y(x);
// ...
...可能性の方が高いですが、まだ許可されていません。
残念ながら、C スタイルの初期化に「戻って」も、考えられるすべての問題が解決されるわけではありません。少なくとも理論的には、直接の初期化ではなくコピーの初期化を行うため、初期化する型には、この初期化を行うためのコピー コンストラクターが必要です。例えば:
class T {
T(T const &) = delete;
public:
T(int) {}
};
int main() {
T t = 1;
}
これは、一時オブジェクトT(int)
を作成するために使用し、その一時オブジェクトからコピー構築するために使用するため、公式には動作が許可されていません。コピー コンストラクターを削除したため、(正式には) 使用できません。ほとんどすべてのコンパイラは通常、コピー コンストラクタをまったく使用せずにジョブを実行するため、これは特に混乱を招く可能性があります。そのため、コードは正常にコンパイルされ、問題なく動作しますが、コンパイラが従おうとするモードをオンにすると、可能な限り標準に近づけると、コードはまったくコンパイルされません。T
T(T const &)
t
一部の人々は、「均一な初期化」の変更を不快に感じ、まったく使用しないことを勧めています。個人的には、私はそれを使用することを好み、単純に縮小変換を行わないようにします (または、縮小変換が避けられない場合は明示的なキャストを使用します)。