std :: Invoke_result_t编译时间语法错误

std::invoke_result_t compile time syntax error

本文关键字:语法 时间 错误 编译 result Invoke std      更新时间:2023-10-16

我正在创建一个函数,该函数可以使用一个值得启发的(一个容器(,并且其开始和结束方法返回迭代符,其解除可以通过传递的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); });

我不想在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*的成员类型。可能会有这样的函数。您是说将其返回类型用于feed std::invoke_result_t

如果是这样,那将是:

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

,但是您可以用简单的Declval缩短它:

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