【问题标题】:C++ const reference initalization and curly braces syntaxC++ const 引用初始化和花括号语法
【发布时间】:2018-12-15 15:23:38
【问题描述】:

我对使用{} 初始化常量引用有点困惑。 所以这是我的代码:

#include <iostream>
#include <initializer_list>

template <typename T>
class Test
{
public:
  Test(std::initializer_list<T> l)
  {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
  }
  Test(const Test<T>& copy)
  {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
  }
  Test() = delete;
};

int main()
{
  Test<int> t1 {100500};

  //here temporary constructed with copy constructor
  //ref1 bound to temporary
  const auto& ref1 = {t1};

  //no temporary, ref2 bound to t1
  const Test<int>& ref2 = {t1};

  //temporary constructed with copy constructor
  //ref3 bound to temporary
  const Test<int>& ref3 = {{t1}};

  return 0;
}

我困惑的根源是这 3 个初始化的不同行为。看起来他们做不同的事情并遵循不同的规则。有人可以澄清每种情况下到底发生了什么吗?

我的操作系统:

Linux Mint 19 塔拉

编译器:

gcc 7.3.0

编译命令:

g++ -std=c++11 -O0 test.cpp -o test -Wall -pedantic

【问题讨论】:

    标签: c++ reference curly-braces


    【解决方案1】:

    对于const auto&amp; ref1 = {t1}

    执行复制列表初始化,ref1 的推导类型为std::initializer_list&lt;Test&lt;int&gt;&gt;,并且在此过程中为 it 元素完成复制初始化,调用Test&lt;int&gt; 复制构造函数。

    注意ref1 中的注释可能会误导你,ref1 的临时绑定不是Test&lt;int&gt; 类型,而是std::initializer_list&lt;Test&lt;int&gt;&gt; 类型。

    const Test&lt;int&gt;&amp; ref2 = {t1}

    这是在复制列表初始化的上下文中有一个特殊的规则,引用绑定用一个元素的大括号初始化,引用直接绑定,没有临时引入。

    const Test<int>& ref3 = {{t1}}
    

    在这种情况下引用不直接绑定,{t1} 需要转换为类型来绑定引用,{t1} 复制初始化一个临时的(Test&lt;int&gt; 复制构造函数调用),该临时用于初始化ref3

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-14
      • 2018-05-14
      • 2018-09-13
      • 2017-06-30
      相关资源
      最近更新 更多