返回值的完美转发?

问题描述 投票:2回答:1

我在超载一个 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;? 哪个更容易理解?

c++ perfect-forwarding
1个回答
5
投票

这样统一的语法,对所有人都适用。constvolatileconstlvaluervalue等,目前不支持隐式对象参数。不过,有一个建议是 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:
    // ...
};

DEMO

另外,请注意,对于一个返回引用的函数,习惯性的做法是在没有任何东西可以返回的情况下抛出一个异常,或者是临时插入并返回一个新的对象。

© www.soinside.com 2019 - 2024. All rights reserved.