返回值的完美转发?

Perfect forwarding for returned value?

我正在超载 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;
        }
    }

但我需要它的副本,它将 return 非常量类型值。我读到我们可以在函数参数可以是 const 或非 const 的情况下使用完美转发(这样我们每次使用它时都将它们包装在 forward<Type> 中),但是如何将它用于值return编辑?

另外,如果我只是想return什么都没有,我应该写return 0;还是return NULL;?哪个更好理解?

这种适用于所有人的统一语法,const/volatile/非const/lvalue/rvalue/etc,目前不支持隐式对象参数。但是,有提案 P0847r4: Deducing this 添加了此功能。有了这个,你可以说:

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:
    // ...
};

DEMO

此外,请注意函数 return 引用的惯用方法是抛出异常,以防无法 returned,或者插入临时和 return一个新对象。