是否可以使用 -1 来获取 container/array 的最后一个元素?
Is it possible to use -1 to fetch the last element of a container/array?
我要的图解如下:
int array[4] { 1, 2, 3, 4 };
auto n1 = array[-1];
assert(4 == n1);
auto n2 = array[-2];
assert(3 == n2);
std::vector coll { 1, 2, 3, 4 };
auto n3 = coll[-1];
assert(4 == n3);
auto n4 = coll[-2];
assert(3 == n4);
我尝试了以下模板函数:
template<typename C, typename I>
constexpr decltype(auto) operator [](const C& coll, I idx)
{
if (idx >= 0)
{
return coll[idx];
}
else
{
return coll[std::size(coll) + idx];
}
}
但是 Clang 抱怨:
error : overloaded 'operator[]' must be a non-static member function
constexpr decltype(auto) operator [](const C& coll, I idx)
是否可以在现代C++中正确实现该功能?
您不能为原始数组重载 operator[]
。
但是你可以只定义一些命名函数,例如,即兴的:
using Index = ptrdiff_t;
template< class Item, size_t n >
auto item( Index const i, Item (&a)[n] )
-> Item&
{ return (i < 0? a[Index( n ) + i] : a[i]); }
那么原始数组的测试代码,经过适当的改编,就像
int array[] { 1, 2, 3, 4 };
int n1 = item( -1, array );
assert( 4 == n1 );
int n2 = item( -2, array );
assert( 3 == n2 );
我留下了像 std::vector
这样的通用集合的定义,作为 reader 的练习。 :)
您还可以使用非成员 std::begin()
函数使上述解决方案更通用(至少对于标准序列容器)。示例:
template <typename C>
auto item(C const& container, int index) -> decltype(*std::cbegin(container))
{
return index >= 0 ?
*(std::cbegin(container) + index) :
*(std::crbegin(container) - index - 1);
}
然后像这样使用它:
std::vector<int> coll{ 1, 2, 3, 4 };
int arra[] { 10, 20, 30, 40 };
auto last = item(coll, -1);
auto secondLast = item(coll, -2);
last = item(arra, -1);
secondLast = item(arra, -2);
return 0;
希望对您有所帮助:)
我要的图解如下:
int array[4] { 1, 2, 3, 4 };
auto n1 = array[-1];
assert(4 == n1);
auto n2 = array[-2];
assert(3 == n2);
std::vector coll { 1, 2, 3, 4 };
auto n3 = coll[-1];
assert(4 == n3);
auto n4 = coll[-2];
assert(3 == n4);
我尝试了以下模板函数:
template<typename C, typename I>
constexpr decltype(auto) operator [](const C& coll, I idx)
{
if (idx >= 0)
{
return coll[idx];
}
else
{
return coll[std::size(coll) + idx];
}
}
但是 Clang 抱怨:
error : overloaded 'operator[]' must be a non-static member function
constexpr decltype(auto) operator [](const C& coll, I idx)
是否可以在现代C++中正确实现该功能?
您不能为原始数组重载 operator[]
。
但是你可以只定义一些命名函数,例如,即兴的:
using Index = ptrdiff_t;
template< class Item, size_t n >
auto item( Index const i, Item (&a)[n] )
-> Item&
{ return (i < 0? a[Index( n ) + i] : a[i]); }
那么原始数组的测试代码,经过适当的改编,就像
int array[] { 1, 2, 3, 4 };
int n1 = item( -1, array );
assert( 4 == n1 );
int n2 = item( -2, array );
assert( 3 == n2 );
我留下了像 std::vector
这样的通用集合的定义,作为 reader 的练习。 :)
您还可以使用非成员 std::begin()
函数使上述解决方案更通用(至少对于标准序列容器)。示例:
template <typename C>
auto item(C const& container, int index) -> decltype(*std::cbegin(container))
{
return index >= 0 ?
*(std::cbegin(container) + index) :
*(std::crbegin(container) - index - 1);
}
然后像这样使用它:
std::vector<int> coll{ 1, 2, 3, 4 };
int arra[] { 10, 20, 30, 40 };
auto last = item(coll, -1);
auto secondLast = item(coll, -2);
last = item(arra, -1);
secondLast = item(arra, -2);
return 0;
希望对您有所帮助:)