gpt4 book ai didi

c++ - 如何确保 std::tuple 在以下代码中使用 c++11 move 语义

转载 作者:行者123 更新时间:2023-11-28 02:59:13 25 4
gpt4 key购买 nike

我编写了一个函数来将函数应用于 std::tuple 如下(基于 "unpacking" a tuple to call a matching function pointer )。我担心元组可能会被复制。我对 move 语义的作用有一个非常基本的概念,并且理解常见字符串示例中的 && 和右值等概念。但我不太了解 std::forward() 之类的工作原理。当还有打包和可变参数编程时,我不确定如何处理它。 (我在周围添加了一些 std::forward 和 &&,很快就会出现编译错误。)

有人可以在这里解释如何使 move 语义对元组起作用吗?另一个问题是,我如何验证(代码的视觉检查除外) move 语义确实适用于代码中的元组?

提前致谢。

#include <tuple>
#include <iostream>
#include <functional>

template<int ...> struct seq {};

template<int N, int ...S> struct gens : gens<N-1, N-1, S...> {};

template<int ...S> struct gens<0, S...>{ typedef seq<S...> type; };

template <typename R, typename Tp, typename ...FArgs>
struct t_app_aux {
template<int ...S>
R static callFunc(std::function<R (FArgs...)> f,Tp t,seq<S...>) {
return f(std::get<S>(t) ...);
}
};

template <typename R, typename Tp, typename ...FArgs>
R t_app(std::function<R (FArgs...)> f, Tp t) {
static_assert(std::tuple_size<Tp>::value == sizeof...(FArgs), "type error: t_app wrong arity");
return t_app_aux<R, Tp, FArgs...>::callFunc(f,t,typename gens<sizeof...(FArgs)>::type());
}

int main(void)
{
std::tuple<int, float, double> t = std::make_tuple(1, 1.2, 5);
std::function<double (int,float,double)> foo1 = [](int x, float y, double z) {
return x + y + z;
};
std::cout << t_app(foo1,t) << std::endl;
}

最佳答案

有您当前实现的拷贝:http://ideone.com/cAlorb我添加了一个带有一些日志的类型:

struct foo
{
foo() : _value(0) { std::cout << "default foo" << std::endl; }
foo(int value) : _value(value) { std::cout << "int foo" << std::endl; }
foo(const foo& other) : _value(other._value) { std::cout << "copy foo" << std::endl; }
foo(foo&& other) : _value(other._value) { std::cout << "move foo" << std::endl; }

int _value;
};

以及申请之前/之后:

std::cout << "Function created" << std::endl;
std::cout << t_app(foo1,t) << std::endl;
std::cout << "Function applied" << std::endl;

它给出:

Function created
copy foo
copy foo
7.2
Function applied

那么,要修复这个添加前向是这样完成的:

template <typename R, typename Tp, typename ...FArgs> 
struct t_app_aux {
template<int ...S>
R static callFunc(std::function<R (FArgs...)> f, Tp&& t, seq<S...>) {
return f(std::get<S>(std::forward<Tp>(t)) ...);
}
};

template <typename R, typename Tp, typename ...FArgs>
R t_app(std::function<R (FArgs...)> f, Tp&& t)
{
static_assert(std::tuple_size<typename std::remove_reference<Tp>::type>::value == sizeof...(FArgs),
"type error: t_app wrong arity");

return t_app_aux<R, Tp, FArgs...>::callFunc(f, std::forward<Tp>(t), typename gens<sizeof...(FArgs)>::type());
}

如您所见,它删除了不需要的拷贝:http://ideone.com/S3wF6x

Function created
7.2
Function applied

唯一的问题是处理 static_assert因为std::tuple_size被称为 std::tuple<>&它没有用。我用了typename std::remove_reference<Tp>::type但也许有一种聪明且更通用的方法?

关于c++ - 如何确保 std::tuple 在以下代码中使用 c++11 move 语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21252869/

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