Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带空括号的默认构造函数 有没有一个很好的理由,一组空括号(圆括号)对于调用C++中的默认构造函数无效? MyObject object; // ok - default ctor MyObject object(blah); // ok MyObject object(); // error_C++_Constructor_Default Constructor_C++ Faq_Most Vexing Parse - Fatal编程技术网

带空括号的默认构造函数 有没有一个很好的理由,一组空括号(圆括号)对于调用C++中的默认构造函数无效? MyObject object; // ok - default ctor MyObject object(blah); // ok MyObject object(); // error

带空括号的默认构造函数 有没有一个很好的理由,一组空括号(圆括号)对于调用C++中的默认构造函数无效? MyObject object; // ok - default ctor MyObject object(blah); // ok MyObject object(); // error,c++,constructor,default-constructor,c++-faq,most-vexing-parse,C++,Constructor,Default Constructor,C++ Faq,Most Vexing Parse,我似乎每次都会自动键入“()”。有没有理由不允许这样做?相同的语法用于函数声明-例如,函数对象,不带参数并返回MyObject,因为编译器认为这是一个不带参数并返回MyObject实例的函数声明。因为它被视为函数声明: int MyFunction(); // clearly a function MyObject object(); // also a function declaration 我猜,编译器不会知道以下语句: MyObject对象() 是一个构造函数调用或函数原型,它声明了一

我似乎每次都会自动键入“()”。有没有理由不允许这样做?

相同的语法用于函数声明-例如,函数
对象
,不带参数并返回
MyObject

,因为编译器认为这是一个不带参数并返回MyObject实例的函数声明。

因为它被视为函数声明:

int MyFunction(); // clearly a function
MyObject object(); // also a function declaration

我猜,编译器不会知道以下语句:

MyObject对象()


是一个构造函数调用或函数原型,它声明了一个名为object的函数,返回类型为MyObject,没有参数。

正如多次提到的,它是一个声明。这是向后兼容的方式。C++的许多领域之一,因为其遗留下来,是愚蠢的/不一致的/痛苦的/虚假的。p> 最烦人的解析

这与所谓的“C++最烦人的解析”有关。基本上,任何可以被编译器解释为函数声明的东西都将被解释为函数声明

同一问题的另一个实例:

std::ifstream ifs("file.txt");
std::vector<T> v(std::istream_iterator<T>(ifs), std::istream_iterator<T>());
或者,如果您有C++11和列表初始化(也称为统一初始化)可用:

std::vector<T> v{std::istream_iterator<T>{ifs}, std::istream_iterator<T>{}};
std::vector v{std::istream_迭代器{ifs},std::istream_迭代器{};

这样,就无法将其解释为函数声明。

您也可以使用更详细的构造方式:

MyObject object1 = MyObject();
MyObject object2 = MyObject(object1);
在C++0x中,这也允许
auto

auto object1 = MyObject();
auto object2 = MyObject(object1);
从n4296[dcl.init]:

[注意:
由于初始值设定项的语法不允许使用
()
xa();
不是类X对象的声明,而是 不带参数并返回X的函数的声明 在某些其他初始化上下文(5.3.4、, 5.2.3, 12.6.2).
-[完注]



正如其他人所说,这是一个函数声明。由于C++11,如果您需要看到空的东西,明确地告诉您使用了默认构造函数,那么可以使用大括号初始化

Jedi luke{}; //default constructor

谢谢-我不会想到在其他代码中声明函数。但我认为这是合法的。有人应该为这篇文章想出一个更好的标题,但我想不出那会是什么。至少可以拼出“构造函数”来帮助搜索引擎,这只是C++的一个很好的例子,其中C++是上下文敏感的。如果
blah
是一个类,那么问题中的示例代码也会失败。我注意到的一点是,如果我只有默认构造函数,那么如果我使用
()
,编译器不会给出任何错误,例如
MyObject object
正常工作&
MyObject()
不会给出任何错误!有人能解释一下原因吗?我的意思是我还没有在我的
main
中定义函数。。。所以它应该给出一个错误,对吗?提前谢谢!挑剔:您可以在函数中声明函数。它在C中称为局部函数,至少
extern“C”foo()在C++中也是允许的。它如何解释为函数?@ CaseBash,<代码> STD::vector < /Cord>是返回类型;code>v
为函数名
打开正式参数列表;
std::istream_迭代器
是第一个参数的类型;
ifs
是第一个参数的名称,
()
周围的
ifs
被有效忽略;第二个
std::istream_迭代器
是第二个参数的类型,未命名,
()
周围的
也被忽略;'));' 关闭参数列表和函数声明。涉及表达式语句和声明的语法中存在歧义:将函数样式显式类型转换作为最左侧子表达式的表达式语句与第一个声明符以(.在这些情况下,声明是一种声明。(C++ISO/IEC(2003)6.8.1)@Constantin,第二个参数后的括号不会被忽略。第二个参数不是
std::istream\u迭代器
,而是指向不带参数并返回
istream\u迭代器
的函数的指针/引用。这需要一个副本构造函数,并且inefficient@Casebash:编译器对我们来说可能足够聪明了e一些
RVO
-像优化一样可以防止它效率低下。“可能”意味着“我在猜测”。关于优化,人们通常不想猜测,而是采取明确的方式。@Stefan:你不需要“猜测”;复制省略将在所有主流编译器中发生,这种情况已经持续了十多年。这并不是好代码。@Casebash因为C++11这里将使用移动赋值运算符,这对于类来说更快,在堆上保存资源。你能为源代码添加链接吗?但它应该会给出一个错误,对吗?因为我们没有定义我定义了
object()
函数,对吗?你能详细解释一下吗?我现在很困惑。提前感谢你!顺便说一句,在我的
main
中,我甚至尝试了这些:
任意变量名随机函数名()
例如
int func1()
双func2()
void func3()
,等等。所有这些都可以运行,即我的程序编译时没有任何错误!但是,我还没有定义这些函数中的任何一个,所以我应该会出错,对吗?@Milan如果您实际尝试调用这些函数,我希望链接器会出错。否则它们只是声明
Jedi luke{}; //default constructor