我有一个结构
template <typename T>
struct Demo {
T x;
T y;
};
我正在尝试编写一个类似于std::get
for tuples 的通用函数,它采用编译时索引I
并返回I
对结构的第 -th 成员的左值引用,如果它被调用时使用左值和对第 -th 成员DemoStruct<T>
的右值引用I
如果使用 rvalue 调用该结构,则为该结构DemoStruct<T>
。
我当前的实现看起来像这样
template <size_t I, typename T>
constexpr decltype(auto) struct_get(T&& val) {
auto&& [a, b] = std::forward<T>(val);
if constexpr (I == 0) {
return std::forward<decltype(a)>(a);
} else {
return std::forward<decltype(b)>(b);
}
}
但是,这并没有达到我的预期,T
而是总是返回一个右值引用。
这是一个显示问题的魔杖盒。
返回对保留传递给函数的结构的值类别的结构成员的引用的正确方法是什么?
编辑:正如 Kinan Al Sarmini 指出的那样,auto&& [a, b] = ...
确实推断出非引用类型a
和b
非引用类型的类型。这也适用于std::tuple
,例如两者
std::tuple my_tuple{std::string{"foo"}, std::string{"bar"}};
auto&& [a, b] = my_tuple;
static_assert(!std::is_reference_v<decltype(a)>);
和
std::tuple my_tuple{std::string{"foo"}, std::string{"bar"}};
auto&& [a, b] = std::move(my_tuple);
static_assert(!std::is_reference_v<decltype(a)>);
编译正常,即使std::get<0>(my_tuple)
返回引用,如下所示
std::tuple my_tuple{3, 4};
static_assert(std::is_lvalue_reference_v<decltype(std::get<0>(my_tuple))>);
static_assert(std::is_rvalue_reference_v<decltype(std::get<0>(std::move(my_tuple)))>);
这是 GCC 和 Clang 中的语言缺陷、故意还是错误?