根据[range.single.view#3], std::ranges::single_view
构造函数之一定义为:
template<class... Args> requires constructible_from<T, Args...> constexpr explicit single_view(in_place_t, Args&&... args);
效果
value_
:如同按初始化value_{in_place, std::forward<Args>(args)...}
。
为什么标准指定使用直接列表初始化({}
)来初始化value_
?为什么不使用直接初始化( ()
) 就像std::optional
,std::variant
和一样std::any
?
此外,std::constructible_from
( std::is_constructible
) 指定T obj(std::declval<Args>()...)
是合式的,而不是T obj{std::declval<Args>()...}
。
考虑以下内容:
ranges::single_view<std::vector<int>> sv(std::in_place, 100, 0);
std::cout << sv.begin()->size() << "\n"; // #1
std::optional<std::vector<int>> op(std::in_place, 100, 0);
std::cout << op->size() << "\n"; // #2
因为使用了不同的初始化,所以#1
会调用std::vector<int>{0, 100}
和打印2
,#2
会调用std::vector<int>(0, 100)
和打印100
。
为什么标准指定对基础值使用大括号初始化,即使它可能会导致不一致?这背后的考虑是什么?