C++ 是否可以使用-1获取容器/数组的最后一个元素?
我想要的说明如下:C++ 是否可以使用-1获取容器/数组的最后一个元素?,c++,templates,c++11,operator-overloading,overloading,C++,Templates,C++11,Operator Overloading,Overloading,我想要的说明如下: 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<ty
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];
}
}
模板
constexpr decltype(自动)运算符[](const C&coll,I idx)
{
如果(idx>=0)
{
返回coll[idx];
}
其他的
{
返回coll[std::size(coll)+idx];
}
}
但Clang抱怨说:
错误:重载的“运算符[]”必须是非静态成员函数
constexpr decltype(自动)运算符[](const C&coll,I idx)
<> P>是否可以正确实现现代C++中的函数? ,对于原始数组,不能超载<代码>运算符[] /COD>。 但您可以定义一些命名函数,例如,即兴:
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]); }
我为一般集合(如
std::vector
)留下一个定义,作为读者的练习。:) 不能为原始数组重载运算符[]
但您可以定义一些命名函数,例如,即兴:
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]); }
我为一般集合(如
std::vector
)留下一个定义,作为读者的练习。:) 您还可以使用非成员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);
}
模板
自动项(C常量和容器,int索引)->decltype(*std::cbegin(容器))
{
返回索引>=0?
*(标准::cbegin(容器)+索引):
*(标准::crbegin(容器)-索引-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;
std::vector coll{1,2,3,4};
int arra[]{10,20,30,40};
自动最后一个=项目(coll,-1);
auto secondLast=项目(coll,-2);
最后=项目(arra,-1);
第二个=项目(arra,-2);
返回0;
希望对您有所帮助:)您还可以使用非成员的
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);
}
模板
自动项(C常量和容器,int索引)->decltype(*std::cbegin(容器))
{
返回索引>=0?
*(标准::cbegin(容器)+索引):
*(标准::crbegin(容器)-索引-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;
std::vector coll{1,2,3,4};
int arra[]{10,20,30,40};
自动最后一个=项目(coll,-1);
auto secondLast=项目(coll,-2);
最后=项目(arra,-1);
第二个=项目(arra,-2);
返回0;
希望对您有所帮助:)您不能使用
运算符[]
,它必须是成员函数。如果(idx>=0),则条件可能是。否则,x[0]
将在数组末尾之外为您提供一个元素,这不会很好地结束:-)问题标题和内容不匹配。请将此注释修复并标记为已过时。请注意:std::size(coll)+idx
将导致在size\u t
范围内的环绕,因为C++17std::size
的返回类型不切实际。您不能使用运算符[]
,它必须是成员函数。如果(idx>=0),则条件可能是
。否则,x[0]
将在数组末尾之外为您提供一个元素,这不会很好地结束:-)问题标题和内容不匹配。请修复此注释并将其标记为已过时。注意:std::size(coll)+idx
将导致在size\t
范围内的环绕,因为C++17std::size
的返回类型不切实际。