C++ 防御性地将std::move应用于可复制类型是否不可取?
假设我们有一个简单的可复制类型:C++ 防御性地将std::move应用于可复制类型是否不可取?,c++,C++,假设我们有一个简单的可复制类型: struct Trivial { float A{}; int B{}; } 它被构造并存储在一个std::vector: class ClientCode { std::vector<Trivial> storage{}; ... void some_function() { ... Trivial t{}; fill_trivial_from_so
struct Trivial
{
float A{};
int B{};
}
它被构造并存储在一个std::vector
:
class ClientCode
{
std::vector<Trivial> storage{};
...
void some_function()
{
...
Trivial t{};
fill_trivial_from_some_api(t, other_args);
storage.push_back(std::move(t)); // Redundant std::move.
...
}
}
class客户端代码
{
std::向量存储{};
...
使某些函数无效()
{
...
平凡t{};
从一些api(t,其他参数)中填充琐碎的;
storage.push_back(std::move(t));//冗余std::move。
...
}
}
通常,这是一个无意义的操作,因为对象无论如何都会被复制
但是,保留std::move
调用的一个优点是,如果将琐碎的
类型更改为不再是琐碎的可复制类型,则客户端代码将不会以静默方式执行额外的复制操作,而是执行更合适的移动。(在我的场景中,这种情况是很可能的,其中平凡类型用于管理外部资源。)
所以我的问题是,应用冗余的std::move
,是否有任何技术上的缺点
但是,保留std::move
调用的一个优点是,如果将琐碎的
类型更改为不再是琐碎的可复制类型,则客户端代码将不会以静默方式执行额外的复制操作,而是执行更合适的移动
这是正确的,你应该考虑一下
所以我的问题是,应用冗余的
std::move
,是否有任何技术上的缺点
取决于移动对象的使用位置。在push_-back
的情况下,一切都很好,因为push_-back
同时具有const T&
和T&
重载,其行为直观
想象一下另一个函数有一个
T&
重载,它的行为与const T&
完全不同:代码的语义将随着std::move
而改变,为什么你要为未来而不是现在编码?一个类似的困境(尽管不相等)然后可能是以后在多线程体系结构中使用一些函数-是否应该过早地为存储添加锁保护?我认为如果这样做,那不是因为防御。如果调用者不使用该值,std::move
将显式显示该值。当然也有技术上的缺点,主要是更多的代码意味着更难阅读,编译器和分析器需要做更多的工作。但这并不能回答你的实际问题。我要说的是,在泛型类型的一般情况下,您将std::move
,而在普通类型的特殊情况下,一般情况下的代码仍然正常工作,因此您必须坚持这一点。但这是一种观点,一种如此不喜欢的观点。@默认有效点。