我在超载一个 operator[]
:
const Type&& operator[](int index) const {
if (index >= size) { std::cout << "Error: excessive index.\n"; return 0; }
else if (index < 0) { std::cout << "Error: negative index.\n"; return 0; }
else {
Node* temp = head->next;
for (int i = 0; i < index; i++) { temp = temp->next; }
return temp->value;
}
}
但我需要一个重复的函数,它将返回非const类型值。我读到,当函数的参数既可以是const也可以是non-const时,我们可以使用完美转发(这样我们就可以把它们包在 forward<Type>
每次我们使用它),但如何使用它来返回的值?
另外,如果我只是想什么都不返回,我是否应该写下 return 0;
或 return NULL;
? 哪个更容易理解?
这样统一的语法,对所有人都适用。const
volatile
非const
lvaluervalue等,目前不支持隐式对象参数。不过,有一个建议是 P0847r4: 扣减此款 它增加了这个功能。有了它,你可以说。
template <typename Self>
auto&& operator[](this Self&& self, int index)
{
if (index >= self.size) { throw std::out_of_range("Error: excessive index"); }
else if (index < 0) { throw std::out_of_range("Error: negative index"); }
auto* temp = self.head;
for (int i = 0; i < index; i++) { temp = temp->next; }
return std::forward_like<Self>(temp->value);
}
在它可用之前,你能做的最好的事情是缩短实现 const
和非const
重载,并将这两个调用委托给一个静态的帮助函数模板,该模板实际上就是 可以 推导出隐式对象参数的cv限定和值类别。
class List
{
private:
template <typename Self>
static auto&& get(Self&& self, int index)
{
if (index >= self.size) { throw std::out_of_range("Error: excessive index"); }
else if (index < 0) { throw std::out_of_range("Error: negative index"); }
Node* temp = self.head;
for (int i = 0; i < index; i++) { temp = temp->next; }
return temp->value;
}
public:
const Type& operator[](int index) const
{
return get(*this, index);
}
Type& operator[](int index)
{
return get(*this, index);
}
private:
// ...
};
另外,请注意,对于一个返回引用的函数,习惯性的做法是在没有任何东西可以返回的情况下抛出一个异常,或者是临时插入并返回一个新的对象。