相关疑难解决方法(0)

带空括号的默认构造函数

有没有什么好的理由在C++中调用默认构造函数时,一组空的圆括号(括号)无效?

MyObject  object;  // ok - default ctor
MyObject  object(blah); // ok

MyObject  object();  // error
Run Code Online (Sandbox Code Playgroud)

我似乎每次都自动输入"()".是不是有一个很好的理由不允许这样做?

c++ constructor c++-faq default-constructor most-vexing-parse

192
推荐指数
8
解决办法
3万
查看次数

缩小C++ 0x中的转换.它只是我,还是听起来像一个突破性的变化?

的C++ 0x将会使下面的代码和类似代码形成不良的,因为它需要一个所谓的收缩转换double一个int.

int a[] = { 1.0 };
Run Code Online (Sandbox Code Playgroud)

我想知道这种初始化是否在现实代码中被大量使用.这个改变将破坏多少代码?如果您的代码受到影响,是否需要在代码中修复此问题?


供参考,参见n3225的8.5.4/6

缩小转换是隐式转换

  • 从浮点类型到整数类型,或
  • 从long double到double或float,或从double到float,除非source是常量表达式,转换后的实际值在可以表示的值范围内(即使它不能精确表示),或者
  • 从整数类型或无范围枚举类型到浮点类型,除非源是常量表达式,转换后的实际值将适合目标类型,并在转换回原始类型时生成原始值,或者
  • 从整数类型或未范围的枚举类型到不能表示原始类型的所有值的整数类型,除非source是常量表达式,并且转换后的实际值将适合目标类型并且将在生成原始值时生成原始值转换回原始类型.

c++ survey aggregate-initialization c++11

82
推荐指数
5
解决办法
7万
查看次数

哪些贪婪的初始化列表示例潜伏在标准库中?

从C++ 11开始,标准库容器和std::string构造函数都采用初始化列表.这个构造函数优先于其他构造函数(甚至,正如@ JohannesSchaub-litb在评论中指出的那样,甚至忽略了其他"最佳匹配"标准).当将所有带括号()的构造函数转换为其支撑版本时,这会导致一些众所周知的陷阱{}

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#include <string>

void print(std::vector<int> const& v)
{
    std::copy(begin(v), end(v), std::ostream_iterator<int>(std::cout, ","));
    std::cout << "\n";
}

void print(std::string const& s)
{
    std::cout << s << "\n";
}

int main()
{
    // well-known 
    print(std::vector<int>{ 11, 22 });  // 11, 22, not 11 copies of 22
    print(std::vector<int>{ 11 });      // 11,     not 11 copies of 0

    // more surprising
    print(std::string{ 65, 'C' });      // AC,     not 65 …
Run Code Online (Sandbox Code Playgroud)

c++ initializer-list c++11 list-initialization

13
推荐指数
1
解决办法
991
查看次数

为什么必须包含<initializer_list>才能使用auto?

在SO上已经有类似的问题,但我想强调braced-init-lists的另一个方面.考虑以下:

auto x = {1}; //(1)
Run Code Online (Sandbox Code Playgroud)

除非<initializer_list>包含标题,否则这是不正确的(8.5.4/2).但为什么?标准说,模板std::initializer_list不是预定义的.这是否意味着,声明(1)引入了一种新类型?在所有其他情况下,auto可以使用的地方如

auto y = expr;
Run Code Online (Sandbox Code Playgroud)

where expr是表达式,auto deduces类型已经存在.另一方面,从逻辑的角度来看,编译器必须为构造分配一个implicite类型{1},std::initializer_list然后是另一个名称.但是在声明(1)中我们不想命名这种类型.那么为什么必须包括这个标题.有类似的情况nullptr.它的类型隐含存在,但要明确指出它必须包括<cstddef>.

c++ types initializer-list auto c++11

5
推荐指数
1
解决办法
1006
查看次数