【问题标题】:Why are explicit constructors not matching when list-initializing function arguments?为什么在列表初始化函数参数时显式构造函数不匹配?
【发布时间】:2017-05-02 01:41:07
【问题描述】:

为了说明这个问题,让我们考虑一下这两个简单的定义,Bar 是一个用户类型,具有来自 int 的显式构造函数:

struct Bar
{
    explicit Bar(int a)
    {}
};

void f(Bar)
{}

现在,正如cppreference 所说:

直接列表初始化(显式和非显式 构造函数被考虑)

我们可以这样初始化一个实例

Bar b1{5};

然而,以这种方式调用函数会出现编译错误

f({5});

它仍然天真地看起来像直接列表初始化 fBar 参数,而且有人可能会争辩说,在参数周围显式使用大括号使其......显式。

禁止对列表初始化函数参数使用显式构造函数的理由是什么?

编辑

链接页面确实是在说在这种情况下这不是直接列表初始化。然而,本着问题的精神,设计语言规则的基本原理是什么,所以这种情况是复制列表初始化而不是直接列表初始化?

【问题讨论】:

  • f({5}) 是复制列表初始化。
  • @T.C.你是对的,这是问题中链接的页面中的第 7 点)。

标签: c++ c++11 parameter-passing language-lawyer list-initialization


【解决方案1】:

因为传递函数参数,所以不是直接列表初始化,而是copy-list-initialization;只能调用非显式构造函数。

function( { arg1, arg2, ... } ) ; (7) 
  • 复制列表初始化(只能调用非显式构造函数)

7) 在函数调用表达式中,使用花括号初始化列表作为 参数和列表初始化初始化函数参数

请注意,在 C++11 之前(即尽管 C++11 功能列表初始化),通过值传递参数给函数始终被视为 copy initialization,而不是直接初始化。

【讨论】:

  • "对于复制列表初始化,不考虑显式构造函数。"没有。
  • @T.C.与“只能调用非显式构造函数”不同吗?我错过了什么吗?
  • 区别是struct A { A(int); explicit A(char); }; A a = 'a' /* OK */, b = {'a'} /* error */;
  • 感谢您提供此参考来解释为什么观察到该行为。但是,您对在语言中以这种方式指定行为的理由有什么解释吗?
  • @AdN 抱歉,我可能无法很好地解释原因;但尽管有新的 C++11 功能列表初始化,但按值向函数传递参数始终被视为 copy initialization
猜你喜欢
  • 2013-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-13
  • 2013-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多