C++函数重载和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测试.cpp-o测试-墙壁-迂腐

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

你错了,

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

因为这两个候选人是:

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

overload_resolution很复杂,但目前,#2是更好的匹配(精确匹配(。

#1

相关内容

最新更新