(包括c++17和c++20,以防解决方案/变通方法不同。)
下面的代码可以工作,
#include <cassert>
#include <range/v3/algorithm/equal.hpp>
#include <range/v3/range/conversion.hpp>
#include <range/v3/view/split.hpp>
#include <range/v3/view/transform.hpp>
#include <string>
#include <vector>
using namespace ranges;
using namespace ranges::views;
int main() {
auto to_string =
#if 0
to<std::string>
#else
[](auto x){ return to<std::string>(x); }
#endif
;
std::string str{"hello world"};
auto strs = str | split(' ');
assert(to_string(*strs.begin()) == "hello");
assert(equal(str | split(' ') | transform(to_string),
std::vector{"hello", "world"}));
}
但是在X1 M2 N1 X分支中将X1 M0 N1 X切换到X1 M1 N1 X使其失败。
lambda的作用与to<std::string>
对象本身有什么不同?
1条答案
按热度按时间k3bvogb11#
lambda的作用与
to<std::string>
对象本身有什么不同?to<std::string>
* 不是 * 对象,它实际上是一个示例化的 * 函数指针 *,它接受一个可默认构造的标签,并返回一个记录指定容器类型的闭包对象(例如,示例中的std::string
)。所以它的类型可以大致拼写为
为了使
r | to<std::string>
工作,range-v3在tag_t
中额外定义了一个管道操作符,它接受这种函数指针类型,大致如下:在您的示例中,当启用
#if 0
分支时,to_string
是接收tag_t
的函数指针,这就是为什么在调用to_string(*strs.begin())
时会出现错误,因为*strs.begin()
返回一个范围,该范围无法转换为tag_t
。要实现上述功能,可以使用
to<std::string>()
(注意这里的括号)直接获取范围适配器闭包对象。值得注意的是,C++23
std::ranges::to
目前 * 不 * 支持省略括号的语法,标准委员会曾讨论过是否支持这一特性(参见issues/527),但遗憾的是,最近被否决了。