重载元组索引运算符 - C++

Overload tuple indexing operator - C++

提问人: 提问时间:7/12/2020 更新时间:11/3/2023 访问量:429

问:

如何重载索引运算符?因此,当我有并且我键入时,我希望它返回对 .这可能吗?[]std::tuple<int,int,int>std::tuple<int,int,int> tuptup[0]get<0>(tup)

C++ 索引 元组运 算符重载 std

评论

0赞 Slava 7/12/2020
为什么不改用呢?std::array<int,3>
0赞 Brian61354270 7/12/2020
你好!你能详细说明一下你为什么要这样做吗?如果需要在运行时按索引查找元组元素,则可能不希望使用元组。
0赞 7/12/2020
我只是想知道这是否可能,我知道重载输入和输出运算符,但想知道索引运算符重载。

答:

0赞 Aykhan Hagverdili 7/12/2020 #1

这是不可能的,原因有 2 个:

  1. operator[]必须是非静态成员函数,并且由于您没有实现标准库,因此无法将成员函数添加到 中。std::tuple

  2. 索引必须是常量表达式,不能使用函数参数强制执行。

1赞 PiotrNycz 7/20/2020 #2

如其他答案中所述 - 不可能将任何成员函数添加到类型中,例如 .并且必须是非静态成员函数。stdstd::tupleoperator[]

但是你可以包装这个元组 - 并添加到这个包装器类型中。在这种情况下,您需要知道元组所有元素的通用返回类型。好吧 - 有 std::any 可以适用于大多数类型。operator[]

这应该有效,但这只是为了满足你的好奇心 - 在实际软件中使用这样的东西将是糟糕的设计:

template <typename Tuple, typename ReturnType = std::any>
class TupleExtractor
{
public:
    TupleExtractor(const Tuple& tuple) 
        : TupleExtractor(tuple, std::make_index_sequence<std::tuple_size_v<Tuple>>{})
    {}
    
    ReturnType operator[](std::size_t index) const
    {
        return extractors[index](tuple);
    }

private:
    template <std::size_t I>
    static ReturnType get(const Tuple& tuple)
    {
        return std::get<I>(tuple);
    }


    template <std::size_t ...I>
    TupleExtractor(const Tuple& tuple, std::index_sequence<I...>) 
        : tuple(tuple), 
          extractors{&TupleExtractor::get<I>...}
    {}

    const Tuple& tuple;
    using Extractor = ReturnType(*)(const Tuple&);
    std::vector<Extractor> extractors;
};

并测试 - 它是否有效:

int main() {
    std::tuple<int, int, int> a{1,2,3};
    TupleExtractor e{a};
    
    return std::any_cast<int>(e[2]);
}

评论

1赞 lrineau 11/3/2023
错字:using Extractor = ReturnType(*)(const Tuple&);