何时通过副本/参考?

When to pass by copy / reference?

本文关键字:参考 副本 何时通      更新时间:2023-10-16

假设我有两个用于operator=重载的模板:

class MyClass {
public:
template <typename T>
std::enable_if_t<true == /* a condition */, MyClass&>
operator=(T value) {
std::cout << "Pass by copy" << std::endl;
}
template <typename T>
std::enable_if_t<false == /* a condition */, MyClass&>
operator=(const T &value) {
std::cout << "Pass by reference" << std::endl;
}
};

std::enable_if一起使用的最佳条件是什么?

我想出了这个:

template <typename T>
struct pass_copy_cond : std::conditional<
std::is_fundamental<T>::value ||
std::is_pointer<T>::value ||
(std::is_trivial<T>::value && sizeof(T) < sizeof(void*))
, std::true_type, std::false_type>::type {};

有没有办法改善病情?

某些检查是多余的:

所有基本类型和指针类型也是微不足道的。诚然,一些基本类型可能大于void*(指向成员/成员函数的指针,尽管它们可能更大,但未被std::is_pointer检测到)。

这是过度约束:

琐碎的可复制性就足够了,琐碎的默认可构造性是无关紧要的。人们甚至可以提出一个理由,仅凭微不足道的可破坏性就足够了。

template <class T>
using prefer_copy = std::bool_constant<std::is_trivially_copyable<T>() && sizeof(T) <= sizeof(std::max_align_t)>;

您将编写两次实现

如果您的编译器允许您强制内联(不是标准化的,但几乎每个编译器都以某种方式允许它),则可以委托给该单一的通用实现并使其内联。