gpt4 book ai didi

c++:具有标记类型访问权限的元组

转载 作者:行者123 更新时间:2023-11-30 05:08:27 25 4
gpt4 key购买 nike

我正在尝试创建一个元组模拟,以便使用相应的标签类型而不是索引来访问其元素。我想出了下一个解决方案(简化):

template<class T> struct tag { using type = T; };
using r = tag<double>;
using t = tag<double>;
using c = tag<int>;
template<class... Ts> class S
{
std::tuple<typename Ts::type&&...> data;
public:
S(typename Ts::type&&... args) : data(std::forward<typename Ts::type>(args)...) {}
};
int main()
{
r::type r0 = 0.;
const t::type t0 = 1.;
auto S0 = S<r, t, c>(r0, t0, 2); // <- error here
//auto T0 = std::forward_as_tuple(r0, t0, 2); // <- works!
}

但是它无法编译(gcc 7.2):

error: cannot bind rvalue reference of type ‘tag<double>::type&& {aka double&&}’ to lvalue of type ‘tag<double>::type {aka double}’
auto S0 = S<r, t, c>(r0, t0, 2);
^
note: initializing argument 1 of ‘S<Ts>::S(typename Ts::type&& ...) [with Ts = {tag<double>, tag<double>, tag<int>}]’
S(typename Ts::type&&... args) : data(std::forward<typename Ts::type>(args)...) {}
^

我发现 std::forward_as_tuple 函数可以正确推断参数类型,所以我的观点是对我的类做同样的事情。有什么提示我做错了吗?

更新:初始描述不完整,抱歉。我的意图不是存储拷贝,而是存储引用(非 const 用于非常量参数,const 用于 const 和右值引用,类似于 std::forward_as_tuple 所做的)。请查看以下更新代码中的注释:

template<class... Ts> class S
{
std::tuple<typename Ts::type...> data;
public:
template<class... Args>
S(Args&&... args) : data(std::forward<Args>(args)...) {}
template<size_t I> auto& get()
{
return std::get<I>(data);
}
};

int main()
{
r::type r0 = 0.;
const t::type t0 = 1.;
auto S0 = S<r, t, c>(r0, t0, 2);
S0.get<0>() = 111; // <- r0 is not changed!
S0.get<1>() = 222; // <- must not be possible!

auto T0 = std::forward_as_tuple(r0, t0, 2);
std::get<0>(T0) = 333; // <- r0 == 333
std::get<1>(T0) = 444; // <- compile error -- can't change const!
}

最佳答案

您需要将构造函数声明为模板:

#include <utility>
#include <tuple>

template<class T> struct tag { using type = T; };
using r = tag<double>;
using t = tag<double>;
using c = tag<int>;
template<class... Ts> class S
{
std::tuple<typename Ts::type...> data; // there is no need to use && here as we want tuple to contain items "as is", not references
public:
template<typename... TArgs>
S(TArgs && ... args) : data(std::forward<TArgs>(args)...) {}
};
int main()
{
r::type r0 = 0.;
const t::type t0 = 1.;
auto S0 = S<r, t, c>(r0, t0, 2); // <- error here
static_cast<void>(S0); // not used
//auto T0 = std::forward_as_tuple(r0, t0, 2); // <- works!
return(0);
}

Run this code online

我想提另一个问题:这种元组实际上不会让你通过标签类型访问元素,因为它允许标签重复。如果您需要按标签类型访问,则需要更彻底地检查标签 <-> 值类型关联。您可能还想检查一些 existing tagged-tuple implementation .

关于c++:具有标记类型访问权限的元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46834078/

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