C ++函数重载和initializer_list构造函数

时间:2018-12-14 15:30:20

标签: c++ constructor overloading initializer-list

这里有一些代码:

#include <string>
#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;
  Test(Test&&) = delete;
};

void f(const Test<Test<std::string>>& x)
{
  std::cout << __PRETTY_FUNCTION__ << std::endl;
}

void f(const Test<std::string>& x)
{
  std::cout << __PRETTY_FUNCTION__ << std::endl;
  f({x});
}

int main()
{
  Test<std::string> t1 {"lol"};
  f(t1);
  return 0;
}

这里的问题是我想在这里调用重载void f(const Test<Test<std::string>>& x)

f({x});

我知道,如果我这样称呼它:

f(Test<Test<std::string>>{x});

它将完成工作。
在第一种情况下,我只是不太了解编译的情况。
我认为f({x})行应该:

  1. 创建临时对象Test<std::string>
  2. 将const引用参数绑定到该对象。
  3. 递归继续并转到步骤1。

相反,它只是一遍又一遍地传递相同的初始对象,并且不会创建任何临时对象。就像x{x}一样。 为什么编译器会那样?

我的操作系统:

  

Linux Mint 19 Tara

编译器:

  

gcc 7.3.0

编译命令:

  

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

1 个答案:

答案 0 :(得分:0)

  

我认为f({x})行应该:
  -创建临时对象测试

您错了,

{x}const Test<std::string>&(身份)构建x

由于2个候选人是:

  • void f(const Test<Test<std::string>>&)#1
  • void f(const Test<std::string>&)#2

overload_resolution很复杂,但目前#2是更好的匹配(完全匹配)。

#1