gpt4 book ai didi

c++ - 为什么 std::function 模板构造函数不使用通用引用?

转载 作者:太空狗 更新时间:2023-10-29 19:55:59 25 4
gpt4 key购买 nike

我认为带通用引用参数的构造函数比不带引用参数的构造函数有更好的性能。

从 cppreference ( https://en.cppreference.com/w/cpp/utility/functional/function/function ),我们可以看到 std::function 的模板构造函数没有使用引用。

template< class F > function( F f );

这是一个错误吗?如果不是,为什么标准不要求构造函数使用通用引用?

编辑:

让我们考虑两种情况。

  1. F是内置类型,这里是一个函数指针,大小为4字节。

使用通用引用:

左值情况:复制 4 个字节。

右值情况:复制 4 个字节。 (您会将 std::move 应用于内置类型吗?)

按值传递:

所有情况:复制 4 个字节。

  1. F 是具有非平凡复制构造函数的类型,例如。按值捕获 std::string 的 lambda 类型。这个例子代表了大多数情况,你同意吗?

使用通用引用:

左值情况:复制构造函数被调用一次

右值情况:移动构造函数被调用一次

按值传递:

左值情况:移动和复制

右值情况:一步

这个分类是否完整?如果是这样,我们可以得出结论,通用引用并不比按值传递差。然后回到原来的问题。

再次编辑:

也许没有捕获的 lambda 是最常见的情况,其中按值传递实际上什么也不传递,而按引用传递是传递指针。这可能是关键。 LWG 2774与这个问题有关。在评论中查看。

最佳答案

因为构造函数移动了它的参数,所以接受一个引用是没有意义的。这归结为关于何时取值的通常建议。

如果你传递一个原语,比如int,通过引用传递是一种悲观化。如果你传递一个复杂类型,比如 std::string,你已经可以 std::move 将它放入参数中(如果你不这样做,那就是因为无论如何你都想要一份拷贝)。您可以两全其美。

// Bog-standard choice between value and ref; original value only observed

void foo(const int& x) { cout << x << '\n'; }
void foo(const int x) { cout << x << '\n'; } // Better!

void foo(const std::string& x) { cout << x << '\n'; } // Better!
void foo(const std::string x) { cout << x << '\n'; }


// When we want to store

void storeACopy(int);
void foo(const int& x) { storeACopy(x); }
void foo(const int x) { storeACopy(x); } // Better!

void storeACopy(std::string);
void foo(const std::string& x) { storeACopy(x); } // Meh
void foo(std::string x) { storeACopy(std::move(x)); } // Cheap!


// So, best of both worlds:
template <typename T>
void foo(T x) { storeACopy(std::move(x)); }

// This performs a copy when needed, but allows callsite to
// move instead (i.e. total flexibility) *and* doesn't require silly
// refs-to-primitives

它还向调用站点发出信号,表明原始对象不会被修改,除非您使用 std::move 明确放弃所有权。

如果相反,该函数采用了引用,那么如果您想要让步,那么您可能会节省一步。。但是,移动应该 super 便宜,所以我们并不担心。而且,如果您不想屈服,那么突然之间您必须在调用点经历冗长的对象拷贝。啊!

此模式是充分利用移动语义的关键。

关于c++ - 为什么 std::function 模板构造函数不使用通用引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57200041/

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