【发布时间】:2021-06-28 18:34:10
【问题描述】:
C++ 容器不包含 const 元素,例如你有const std::vector<int>,而不是std::vector<const int>。
当我尝试根据传递的容器是否为 const 来调整函数的返回值类型时,这有点不幸。
这里是励志例子,请不要过多关注算法或boost的使用,我只使用它,因为C++ optional不支持引用。
这段代码appears to work,但是代码看起来很丑,所以我想知道概念是否为我们提供了一种以更好的方式编写它的方法。 我认为不是,因为基本上概念只是谓词,但我希望有一些好的东西,特别是返回类型非常垃圾。
template<typename C>
using match_const = std::conditional_t< std::is_const_v<std::remove_reference_t<C>>,
const typename std::remove_reference_t<C>::value_type,
typename std::remove_reference_t<C>::value_type>;
// no constraints
auto ofind(auto& container, const auto& value) -> boost::optional<match_const<decltype(container)>&> {
if (auto it = std::ranges::find(container, value); it!=container.end()){
return *it;
}
return boost::none;
}
// dummy concept
template<typename C>
concept Container = requires (C c){
{c.begin()};
{c.end()};
{c.size()} -> std::same_as<size_t>;
};
// constraints version
auto ofind2(Container auto& container, const auto& value) ->boost::optional<match_const<decltype(container)>&>{
if (auto it = std::ranges::find(container, value); it!=container.end()){
return *it;
}
return boost::none;
}
如果我的问题太模糊,这里是我的理想化版本:
boost::optional<Container::real_reference> ofind(Container auto& container, const auto& value)
其中 Container::real_reference 是与向量中的引用 typedef 不同的常量匹配的东西,例如考虑这个:
using CVI = const std::vector<int>;
static_assert(std::is_same_v<int&, CVI::reference>); // compiles
注意:我知道我应该使第二个参数也受到更多限制,但为简单起见,我将其保留为 const auto&。
【问题讨论】:
-
你不需要
boost::optional<decltype(*container.begin())&>吗? -
您不必为使用
boost::optional而道歉,std::optional只是随意缺少功能不是您的错。 -
"C++ 容器不包含 const 元素" - 如果您在示例中声明它们,它们会:
std::vector<const int>。 -
@Barry 我只是想抢占人们的注意力,因为我的问题基本上与 boost::optional 无关,它可能是 (gasp) 原始的是否为 const 的指针。 :)
-
@TedLyngmo 除了
vector<T const>不是一个东西。
标签: c++ c++20 c++-concepts