哪个声明是C ++ / C中的标准?

时间:2013-10-18 14:32:58

标签: c++ c declaration

以下哪项声明是标准和首选?

int x = 7;

int x(7);

4 个答案:

答案 0 :(得分:4)

int x(7);

有效的声明&在C中初始化变量;

我建议你找一本学习C的好书并使用一个好的编译器。

答案 1 :(得分:1)

您使用的c种语言 int x = 7;

答案 2 :(得分:1)

你已经将这个问题标记为C和C ++,但两者的答案并不相同。

在C中,int x(7);根本不起作用。它甚至不会编译。由于此表单在C中根本不起作用,因此首选表单为int x = 7;

在C ++中,int x(7);有效 - 但你必须小心,因为这种形式可以导致"most vexing parse";如果括号中的任何内容都可以解释为类型而不是值,则会将其解析为声明名为x的函数,该函数返回int而不是使用int定义int x();括号中指定的值。同样,如果你将parens留空:int x{7};你最终会得到一个函数声明。

C ++确实有另一种形式:T id { x };。有人称之为“通用初始化”。它确实消除了任何歧义 - 类似于T,其中id类型必须x的定义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);
    // ...

这不太可能发生在我上面所示的文字中,但类似于:

class T {
    T(T const &) = delete;
public:
    T(int) {}
};

int main() {
    T t = 1;
}

......更有可能 - 而且仍然是不允许的。

不幸的是,回到C风格的初始化并不能解决所有可能出现的问题。至少在理论上,它会复制初始化而不是直接初始化,因此您初始化的类型必须具有可用于执行此初始化的复制构造函数。例如:

T(int)

这不是正式允许的,因为它应该做的是使用T创建一个临时的T(T const &)对象,然后使用t来复制构造{{1从那个临时的。由于我们删除了复制构造函数,因此无法(正式)使用它。这可能会特别令人困惑,因为几乎所有编译器通常都会在不使用复制构造函数的情况下完成工作,所以代码通常编译并且工作正常 - 但是你打开模式的那一刻在编译器尽可能接近标准的情况下,代码根本不会编译。

有些人发现“统一初始化”的变化如此令人反感,以至于他们建议不要使用它。就个人而言,我更喜欢使用它,只是确保我没有进行任何缩小的转换(或者如果无法避免缩小转换,则使用显式转换)。

答案 3 :(得分:0)

一般

int x = 7;

是标准方式,也是C中的唯一方式。

但是,在C ++中,您可以在构造函数初始化列表中使用x(7)初始化int,在这种情况下,您必须为正在初始化的每个变量调用“构造函数”。对于基元,可以使用x(7)语法执行此操作。