代码之家  ›  专栏  ›  技术社区  ›  Adam

std::invoke\u result\u t编译时语法错误

  •  0
  • Adam  · 技术社区  · 7 年前

    我正在创建一个函数,它接受一个iterable(容器),它的begin和end方法返回迭代器,迭代器的解引用可以通过传递的lambda修改。这听起来很复杂,但我想做一些类似Python的超级整洁

    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); });
    

    我不想硬编码 uint64_t 在invoke\u结果中 IteratorWrapper::operator* 。它应该是的返回类型 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:
    
    1 回复  |  直到 7 年前
        1
  •  3
  •   Guillaume Racicot    7 年前

    你期待什么 typename Iterator::operator* 屈服?A型?函数指针?函数指针的类型?

    没有名为的成员类型 operator* 。可能有一个这样命名的函数。你的意思是把它当作回程饲料吗 std::invoke_result_t ?

    如果是这样,那将是:

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

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

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