从容器中获取元素常量限定的通用方法
Generic way of getting const-qualification of elements from container
我需要一个泛型函数,它可以对容器进行常量或非常量引用,并返回对根据容器限定的元素的相应引用。
大致如下:
template <typename C>
auto get_nth( C& c, int i ) -> /* not-sure-what, but let's call it T */
{
//.... some tricky code here ...
}
我想强调的是,如果C扩展到
SomeContainer const
那么T就是
SomeContainer::const_reference
以及其他
SomeContainer::reference
我想我可以用类型特征和mtl把它放在一起,如果,我的问题是是否有一种更短、更干净的方法。
我使用的是C++x11(显然)和boost。
提前谢谢。
我认为您正在寻找typename C::reference
,请参阅23.2.1[container.requirements.general]§4。
哦,等等,如果C
已经是const
,那么上面的内容就不起作用了。但等一下,decltype
来救援!
template <typename C>
auto get_nth( C&& c, int i ) -> decltype(*c.begin())
{
//.... some tricky code here ...
}
如果您还想支持没有begin
成员函数的C样式数组:
#include <iterator>
template <typename C>
auto get_nth( C&& c, int i ) -> decltype(*std::begin(c))
{
//.... some tricky code here ...
}
而且实现真的不是那么棘手:
#include <iterator>
template <typename C>
auto get_nth( C&& c, int i ) -> decltype(*std::begin(c))
{
auto it = std::begin(c);
std::advance(it, i);
return *it;
}
注意,上面的解决方案接受左值和右值,但它将始终返回一个左值引用。根据客户端代码的不同,这可能是一个性能问题。以以下代码为例:
std::string s = get_nth(std::vector<std::string> { "hello", "world" }, 0);
这将把结果复制到s
中,即使移动它是完全有效的(当然,速度更快)。
为了解决这个问题,我们需要两个重载,一个用于左值,另一个用于右值:
#include <iterator>
#include <type_traits>
template <typename C>
auto get_nth( C& c, int i ) -> decltype(*std::begin(c))
{
auto it = std::begin(c);
std::advance(it, i);
return *it;
}
template <typename C>
auto get_nth( C&& c, int i )
-> typename std::enable_if<std::is_rvalue_reference<C&&>::value,
decltype(std::move(*std::begin(c)))>::type
{
auto it = std::begin(c);
std::advance(it, i);
return std::move(*it);
}
现在,结果将移动到s
中。enable_if
部分是必要的,因为由于引用折叠规则,C&&
也可以绑定到lvalues,然后初始化s
的调用将是不明确的。
相关文章:
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 是否有内置方法可以强制转换为不同的基础类型,但保留常量限定符?
- 为什么常量方法可以采用非常量引用?
- 常量方法中的非常量 lambda 捕获
- 友元方法作为常量
- 一个模板方法,用于同时接受常量和非常量参数
- 使用大量已知常量变量的正确方法
- 使用迭代器替换映射中的常量项的方法
- 一种优雅或至少可行的方法,用于使用和接受具有重载方法和运算符的不同大小的文字数组常量
- 初始化不是整数的巨大常量多维数组的最佳方法是什么?
- Gmock 常量方法不调用,而是调用原始方法
- 为什么我们需要常量方法?
- 从模块导出全局常量的正确方法是什么?
- 模板常量/非常量方法
- 定义常量变量的最佳方法
- 常量字符*的模板方法专用化
- 常量静态成员函数:有另一种方法可用吗?
- 使方法常量后声明不兼容
- c++ 是否提供了一种使整个结构常量(不可修改)的方法?
- 当底层OpenGL状态被修改时,我应该声明一个方法常量吗