为什么在 hana::always 中包装对按值返回的函数的调用来规避 ranges::views::join 的要求?或者也许不是?
Why wrapping call to function returning by value in hana::always circumvent requirements of ranges::views::join? Or maybe it doesn't?
这个函数,输入任何 int
,returns a std::vector<int>
按值:
auto make = [](int){
return std::vector<int>{1,2,3};
};
所以,这样的事情是行不通的
std::vector<int> v{1,2,3};
auto z = v | std::ranges::views::transform(make)
| std::ranges::views::join; // fails to compile
因为,我理解(但如果我错了请纠正我),当包含在 join
中的迭代器前进时,它会通过 make
触发向量的生成,但是那些join
中的迭代器被取消引用时,临时对象已经被销毁。
但是,以下不会失败:
std::vector<int> v{1,2,3};
auto z = v | std::ranges::views::transform(boost::hana::always(make(int{})))
| std::ranges::views::join;
这是为什么?使用 always
引入了什么机制?
我认为下面是两个函数的证明,make
和always(make(int{}))
,return暂时。我是不是搞错了?
static_assert(!std::is_reference_v<decltype(make(int{}))>);
static_assert(!std::is_reference_v<decltype(boost::hana::always(make(int{}))(int{}))>);
有两个不同的问题。
join_view
对纯右值范围的连接范围的限制是 C++20 中的一个缺陷,已被 P2328R1 纠正。 transform(make) | join
应该只在实现缺陷解决方案的标准库上工作(例如 libstdc++ trunk)。
hana::always
returns 不同的事情取决于它是作为左值还是右值调用。它 returns 当作为左值调用时是左值引用,当作为右值调用时是纯右值。 transform
始终作为左值调用,而您的 static_assert
正在检查作为右值调用的结果。
这个函数,输入任何 int
,returns a std::vector<int>
按值:
auto make = [](int){
return std::vector<int>{1,2,3};
};
所以,这样的事情是行不通的
std::vector<int> v{1,2,3};
auto z = v | std::ranges::views::transform(make)
| std::ranges::views::join; // fails to compile
因为,我理解(但如果我错了请纠正我),当包含在 join
中的迭代器前进时,它会通过 make
触发向量的生成,但是那些join
中的迭代器被取消引用时,临时对象已经被销毁。
但是,以下不会失败:
std::vector<int> v{1,2,3};
auto z = v | std::ranges::views::transform(boost::hana::always(make(int{})))
| std::ranges::views::join;
这是为什么?使用 always
引入了什么机制?
我认为下面是两个函数的证明,make
和always(make(int{}))
,return暂时。我是不是搞错了?
static_assert(!std::is_reference_v<decltype(make(int{}))>);
static_assert(!std::is_reference_v<decltype(boost::hana::always(make(int{}))(int{}))>);
有两个不同的问题。
join_view
对纯右值范围的连接范围的限制是 C++20 中的一个缺陷,已被 P2328R1 纠正。transform(make) | join
应该只在实现缺陷解决方案的标准库上工作(例如 libstdc++ trunk)。hana::always
returns 不同的事情取决于它是作为左值还是右值调用。它 returns 当作为左值调用时是左值引用,当作为右值调用时是纯右值。transform
始终作为左值调用,而您的static_assert
正在检查作为右值调用的结果。