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
,而在普通类型的特殊情况下,一般情况下的代码仍然正常工作,因此您必须坚持这一点。但这是一种观点,一种如此不喜欢的观点。@默认有效点。