c++ - std::invoke_result_t 编译时语法错误

标签 c++ iterator

我正在创建一个函数,它接受一个可迭代对象(一个容器),它的开始和结束方法返回迭代器,其解引用可以通过传递的 lambda 进行修改。听起来很复杂,但我正在尝试做一些像 Python super 整洁的事情

modified_iterator = (fn(x) for x in my_iterator)

代码:

    template<typename Container, typename Fn>
    class IterableWrapper {
    public:
        template<typename Iterator>
        class IteratorWrapper : public Iterator {
        public:
            template<typename ...Args>
            explicit IteratorWrapper(Fn fn, Args ... args) : Iterator(args ...), fn(fn) {}

            //typename std::invoke_result_t<Fn, typename std::invoke_result_t<typename Iterator::operator*>> not working
            typename std::invoke_result_t<Fn,uint64_t> operator* () const {
                return fn(Iterator::operator*());
            }
        private:
            Fn fn;
        };

        IterableWrapper(const Container&& c, Fn&& fn) : c(std::move(c)), fn(std::forward<Fn>(fn)) {}

        auto begin() const {
            return IteratorWrapper<decltype(c.begin())>(fn, c.begin());
        };

        auto end() const {
            return IteratorWrapper<decltype(c.end())>(fn, c.end());
        };

    private:
        Container c;
        Fn fn;
    };

    template<typename C, typename Fn>
    auto wrap_iterable(C& c, Fn&& fn) = delete;

    template<typename C, typename Fn>
    auto wrap_iterable(C&& c, Fn&& fn) {
        return IterableWrapper<C, Fn>(std::move(c), std::forward<Fn>(fn));
    }

期望的用法:

    auto new_iterable = wrap_iterable(std::vector<uint64_t>{1,2,3,4}, [](auto&& item) { return std::pow(item, 2); });

我不想在 IteratorWrapper::operator* 的 invoke_result 中对 uint64_t 进行硬编码。它应该是基类中operator*的返回类型(即模板化类型Iterator)。

但是用注释掉的返回类型替换硬编码的头给我一个编译错误。新标题:

typename std::invoke_result_t<Fn, typename std::invoke_result_t<typename Iterator::operator*>> operator* () const

错误:

In file included from /Users/adam/school/cpp/invertedindex/main.cpp:203:0:
/Users/adam/school/cpp/invertedindex/inverted_index.hpp:61:105: error: template argument 1 is invalid
             typename std::invoke_result_t<Fn, typename std::invoke_result_t<typename Iterator::operator*>> operator* () const {  // typename std::invoke_result_t<Fn, typename std::invoke_result_t<typename Iterator::operator*>> not compiling??
                                                                                                         ^~
/Users/adam/school/cpp/invertedindex/inverted_index.hpp:61:121: error: template argument 2 is invalid
             typename std::invoke_result_t<Fn, typename std::invoke_result_t<typename Iterator::operator*>> operator* () const {  // typename std::invoke_result_t<Fn, typename std::invoke_result_t<typename Iterator::operator*>> not compiling??
                                                                                                                         ^~~~~
/Users/adam/school/cpp/invertedindex/inverted_index.hpp:61:127: error: expected identifier before '{' token
             typename std::invoke_result_t<Fn, typename std::invoke_result_t<typename Iterator::operator*>> operator* () const {  // typename std::invoke_result_t<Fn, typename std::invoke_result_t<typename Iterator::operator*>> not compiling??
                                                                                                                               ^
/Users/adam/school/cpp/invertedindex/inverted_index.hpp:61:127: error: expected unqualified-id before '{' token
In file included from /Users/adam/school/cpp/invertedindex/main.cpp:203:0:

最佳答案

您希望 typename Iterator::operator* 产生什么结果?一种?函数指针?一种函数指针?

没有名为operator* 的成员类型。可能有一个以这种方式命名的函数。您的意思是将其返回类型提供给 std::invoke_result_t 吗?

如果是这样,那就是:

std::invoke_result_t<decltype(&Iterator::operator*), Iterator>

但是你可以用一个简单的 declval 来缩短它:

decltype(*std::declval<Iterator>())

关于c++ - std::invoke_result_t 编译时语法错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50091034/

相关文章:

c++ - boost fusion 将较小的序列复制到较大的序列中

c++ - 在遍历多个集合时写回迭代器

c# - 迭代时更改集合中的项目字段是否会使集合无效?

collections - 为什么不能收集一系列字符?

c++ - 在类声明中使用类型定义迭代器的问题

c++ - 需要一个关于如何使用 QThreadPool 的工作示例

c++ - 使用 GDB 修复大型项目中的双重释放或损坏 (!prev) 错误

c++ - 表示函数参数的元组的类型表达式

C++ VS2013 调试器断点 : Not Hit

c++ - 设计迭代器包装器