完美转发返回值?

Mar*_*ian 5 c++ perfect-forwarding

我正在重载一个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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

另外,如果我只想什么都不返回,我应该写return 0;还是return NULL;?哪个更容易理解?

Pio*_*cki 5

这种统一的语法,将所有的工作,const/ volatile/无const/左值/右值的/ etc。,隐式对象参数目前还不支持。但是,有提案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);
}
Run Code Online (Sandbox Code Playgroud)

在它可用之前,您可以做的最好的事情是缩短重载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:
    // ...
};
Run Code Online (Sandbox Code Playgroud)

演示

另外,请注意,返回引用的函数的惯用方法是在无法返回任何内容的情况下抛出异常,或者插入临时并返回一个新对象。