Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/413.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 转发与不转发传递给包装器的函数_C++_Templates_Generic Programming_Function Object_Forwarding Reference - Fatal编程技术网

C++ 转发与不转发传递给包装器的函数

C++ 转发与不转发传递给包装器的函数,c++,templates,generic-programming,function-object,forwarding-reference,C++,Templates,Generic Programming,Function Object,Forwarding Reference,我的问题是完美转发传递给包装器的函数有什么好处 template<typename T, typename ...U> auto time_function(T&& func, U&& ...args) { std::cout<<"timing void function"<<std::endl; //std::forward<T>(func)(std::forward<U>(ar

我的问题是完美转发传递给包装器的函数有什么好处

template<typename T, typename ...U>
    auto time_function(T&& func, U&& ...args)
{
    std::cout<<"timing void function"<<std::endl;
    //std::forward<T>(func)(std::forward<U>(args)...); //this vs next one
    func(std::forward<U>(args)...);

    std::cout<<"timing over"<<std::endl;
}
模板
自动时间函数(T&&func,U&&args)
{

std::cout假设我有一个有状态赋值函数。赋值函数将重复使用多次,因此每次都必须复制该值。但是,如果赋值函数是右值,它可以只移动该值:

struct Assignor {
    std::string value;
    void operator()(std::string& dest) const &
    {
        dest = value;
    }
    void operator()(std::string& dest) &&
    {
        dest = std::move(value);
    }
};
现在,完美转发对右值产生了影响:

Assignor f{std::string(10000, 'X')};
std::string a, b, c;

time_function(f, a);                                 // copies the string
time_function(std::move(f), b);                      // should move the string
                                                     // but copies if you don't std::forward
time_function(Assignor{std::string(10000, 'Y')}, c); // same
(这只是一个函子如何优化w.r.t.值类别的例子。我知道它看起来有点做作,但人们总能想出创造性的想法。)


顺便说一下,您应该使用,而不是直接调用
()

std::invoke(std::forward(func)、std::forward(args)…);

除了L.F.的回答之外,我想就一个潜在的问题做一个小说明,这是显而易见的,但仍然可以忽略:有时通过通用引用传递函数对象并将其作为右值调用是危险的。假设

void time_function(T&& func, ...)
调用一次std::forward(func)(…)

void for_each(T&& func, ...)

可能多次调用
std::forward(func)(…)
。然后在第一次调用之后,所有进一步的调用都不安全。在L.F.的示例中,这对应于来自“moved from”状态的多个赋值:在第一次赋值之后,
std::string value
成员将保留在“有效但未指定的状态”,以后的赋值将不会执行预期的操作(尽管它们不会是UB)。如果
赋值器
没有
运算符()
,问题不会出现。

完美转发可以防止不必要的复制,提高性能。既然我们已经进入了函数,复制不是已经完成了吗,因为它里面是一个左值?我不熟悉const&和&&在一个functor之后,我们通常在成员函数上使用const来表示self对象没有被该函数修改s成员函数。在这个上下文中,const&和&&是什么意思?@SridharThiagarajan这样想:
f(x)
f(x{})
分别调用全局函数
void f(const x&);
void f(x&&);
调用成员函数const&;和
void f()&&;
void for_each(T&& func, ...)