std::ranges::elements_view,用于自定义类似元组的数据
std::ranges::elements_view for custom tuple-like data
我有一个用例可以简化为:
#include <vector>
#include <ranges>
#include <tuple>
struct TDat
{
double x, y;
template <std::size_t I>
friend double &get(TDat &Dat)
{ if constexpr (I == 0) return Dat.x; else return Dat.y; }
template <std::size_t I>
friend double const &get(TDat const &Dat)
{ if constexpr (I == 0) return Dat.x; else return Dat.y; }
};
namespace std
{
template <>
struct tuple_size<TDat> : integral_constant<size_t, 2u> {};
template <size_t I>
struct tuple_element<I, TDat>
{ using type = double; };
} // std
class TTable
{
private:
std::vector<TDat> DatVec;
public:
auto GetxVec()
{ return std::views::keys(DatVec); }
};
这段代码不使用G++10编译,因为TDat
不为__has_tuple_element<std::ranges::range_value_t<_Vp>, _Nm>
建模。问题似乎是,这个概念被定义为(https://github.com/gcc-mirror/gcc/blob/fab263ab0fc10ea08409b80afa7e8569438b8d28/libstdc%2B%2B-v3/include/std/ranges#L3318(:
namespace __detail
{
template<typename _Tp, size_t _Nm>
concept __has_tuple_element = requires(_Tp __t)
{
typename tuple_size<_Tp>::type;
requires _Nm < tuple_size_v<_Tp>;
typename tuple_element_t<_Nm, _Tp>;
{ std::get<_Nm>(__t) }
-> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
};
}
我相信,由于对get
的调用是限定的,所以编译器找不到我的get
函数。这个结论正确吗?如果是,这是预期行为吗?在std
命名空间中定义get函数是定义行为吗?
我相信,由于对get的调用是限定的,所以编译器找不到我的
get
函数。这个结论正确吗?
是。
如果是,这是预期行为吗?
这至少是指定的行为。[range.elements.view]将概念定义为:
template<class T, size_t N>
concept has-tuple-element = // exposition only
requires(T t) {
typename tuple_size<T>::type;
requires N < tuple_size_v<T>;
typename tuple_element_t<N, T>;
{ get<N>(t) } -> convertible_to<const tuple_element_t<N, T>&>;
};
除非另有说明,否则标准库中的所有函数调用都是隐式完全限定的[library.contents]/3:
每当提到在标准库中定义的名称
x
时,除非另有明确说明,否则假定名称x
完全限定为::std::x
。
此处没有其他说明。
然而,它是否有意是另一个问题。答案也是肯定的。图书馆实际上并没有一个";TupleLike";概念是的。是的,结构化绑定是存在的,但库中还没有对此进行正式规范——因此,在这之前,所有类似元组的算法都只适用于标准库的类似元组的东西(pair
、array
、tuple
等(
在std命名空间中定义get函数是定义行为吗?
不,你可能不会。
相关文章:
- C++:TypeDef使用元组
- Pybind11:将元组列表从Python传递到C++
- 重载元组索引运算符-C++
- 在C++中,如何通过几种类型从元组中选择多个元素
- 将fold表达式与std::一起用于两个元组
- std::ranges::elements_view,用于自定义类似元组的数据
- 将元组的向量转换/构造为堆
- 专用于 std 元组的模板,而无需用户执行remove_cvref
- 将元组的向量构造成堆
- C++中的可变长度数组/数据结构
- 时间复杂度 当具有复合数据类型(如元组或对)时?
- 可变参数模板与使用元组在参数中添加不同的数据对
- 访问和打印元组中的数据,并使用 C++14 使用模板函数显示数据
- 创建一个伪元组,一个存储在其他地方的数据的前端
- 对boost元组的数据进行排序
- 用于存储唯一<键,值>元组的数据结构,其中<value>最小值
- 用于存储元组键的数据结构:参数关系列表
- 元组的数据存储在哪里
- 根据数据类型,展开后可变元组顺序会发生变化
- 模板递归区分boot::元组中的数据类型