gpt4 book ai didi

c++ - 我应该通过 const 引用还是通过模板函数中的值传递?

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:25:00 24 4
gpt4 key购买 nike

选择通过 const 引用与值时,大型类别的选择似乎很清楚:Gotta使用 const ref以避免使用昂贵的复制仅在 limited circumstances 中允许(如果复制构造函数没有副作用,或者如果拷贝来自右值)。

对于 smaller classes ,似乎按值传递更有吸引力:

  • 它和取消引用一样快
  • 它避免了别名(这既容易出错又不利于性能,因为它迫使编译器更加保守)
  • 如果无论如何都需要复制,它会在编译器可能能够使用复制省略的范围内进行复制

那么,当编写模板函数时,参数的类是大还是小并不总是很明显,那么最佳实践是什么?

最佳答案

(假设您只想读取传递的值。)

我认为最好的选择是路过const& ,如:

  • 某些对象无法复制、复制成本高昂或在其复制构造函数中包含副作用。

  • 同时通过 const& 获取原语可能会导致轻微的性能下降,与上面要点中描述的问题相比,这是一个较小的损失。


理想情况下,你会想要做这样的事情(我不小心这里的复制构造函数中有副作用的小类):

template <typename T>
using readonly = std::conditional_t<
sizeof(T) <= sizeof(void*),
T,
const T&
>;

template <typename T>
void foo(readonly<T> x);

问题是T无法从对 foo 的调用中推导出来, 因为它在 "non-deducible context" 中.

这意味着您的用户必须调用 foo<int>(0)而不是 foo(0) , 作为 T=int无法从编译器中推导出来。

(我想重申,我在上面使用的条件非常天真并且有潜在的危险。您可能只想检查 T 是原始数据还是小于 void* 的 POD。)


您可以做的另一件事是使用 std::enable_if_t控制调用什么函数:

template <typename T>
auto foo(T x) -> std::enable_if_t<(sizeof(T) <= sizeof(void*))>;

template <typename T>
auto foo(const T& x) -> std::enable_if_t<(sizeof(T) > sizeof(void*))>;

live example on wandbox

这显然需要很多额外的样板...当(如果?)我们将得到 constexpr 时,也许会有更好的代码生成解决方案。 block 和“元类”。

关于c++ - 我应该通过 const 引用还是通过模板函数中的值传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44884545/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com