gcc是否有std::vector::template_back的扩展重载



根据cppreference,std::vector::emplace_back只有一个签名,即:

template< class... Args >
reference emplace_back( Args&&... args );

在描述中,它说emplace_back应该将其每个参数转发给vector中类型的构造函数。然而,当我使用gcc 12.2测试以下代码时,它成功地编译了:

#include <iostream>
#include <vector>
class Foo
{
public:
int x;
int y;
Foo(int x, int y) : x(x), y(y)
{}
};
int main()
{
std::vector<Foo> foos;
Foo foo(1, 2);
foos.push_back(std::move(foo));
foos.emplace_back(foo); // weird
}

(请参阅编译器资源管理器(

我原以为foos.emplace_back(foo);行编译失败。似乎emplace_back有这种过载:

template< class T >
reference emplace_back( T& arg );

文档中没有提到。我是遗漏了什么,还是这只是一个编译器扩展?

foos.emplace_back(foo); // weird

真奇怪!您请求emplace_back,这意味着您正在调用构造函数,并将foo传递给构造函数。因此,您正在调用复制构造函数。push_back也会这么做!

这是一个隐式定义的默认复制构造函数,请参阅复制构造函数上的cppreference:

如果没有为类类型(结构、类或联合(提供用户定义的复制构造函数,编译器将始终将复制构造函数声明为其类的非显式内联公共成员。

您没有定义复制构造函数,所以编译器按照C++的要求为您定义了复制构造函数。你可以避免这种情况,并使你的编译失败:

class Foo
{
public:
int x;
int y;
Foo(int x, int y) : x(x), y(y)
{}

//! Explicitly deleted default copy constructor.
Foo(const Foo&) = delete;
};
foos.push_back(std::move(foo));

他正在调用move构造函数。请注意,您在离开foo之后使用它,这或多或少是非法的(将std::move扔到foo意味着foo不再应该拥有任何资源。(

如果您真的只想删除move构造函数,语法基本相同:Foo(Foo&&) = delete;

template< class... Args >
reference emplace_back( Args&&... args );

可以推断为类似(用Args = Foo&(的东西

reference emplace_back( Foo& && args[0] );

崩溃为

reference emplace_back( Foo& args[0] );

相关内容

  • 没有找到相关文章

最新更新