【问题标题】:Using double braces e.g. Foo{{initializer list}} to resolve ambiguity使用双括号,例如Foo{{initializer list}} 解决歧义
【发布时间】:2015-01-18 23:06:26
【问题描述】:

最近有人证明了 C++ 的可怕性 (here):

cout << string(50, 'x'); // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
cout << string{50, 'x'}; // 2x

std::string 将第二行视为初始化列表。

我非常喜欢使用 {} 初始化器语法,但是我即将实现一个可以使用初始化器列表进行初始化的类。

有没有办法编写以下语法:

Foo{x};        // initialise a Foo object with x
Foo{{x,y,z}};  // initialise a Foo object with initialiser list
Foo{{x}};      // initialise a Foo object with initialiser list with ONE item

【问题讨论】:

  • @remyabel, string{50, 'x'} -- 我们是使用 char 和重复计数还是使用 char 列表进行初始化?编译器通过更喜欢后者来解决歧义,但我想在语法上解决它,以使我的代码更好地阅读。
  • @Pi:当然是字符列表。拥有两种形式的动机之一是因为您希望允许两种行为(特别是您在示例中展示的两种行为)。
  • string{50,'x'} 使用 initializer-list 并且文档说它使用列表的内容构造字符串,因此是字符列表...
  • 您是否尝试过重载 X 和 std::initializer_list{x} 上的构造函数?当给定一个对象而不是给定一个对象的列表时,您想做任何不同的事情吗?
  • 如果你有一个初始化列表构造函数,Foo{x}; 会去那个,除非它完全不可行。

标签: c++ c++11 initializer-list


【解决方案1】:

最后我通过让我的类使用可变参数包而不是初始化列表来解决了这个问题。

我还没有遇到过不能以这种方式绕过初始化列表的示例。

【讨论】:

    猜你喜欢
    • 2017-10-03
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多