简体   繁体   中英

std::invoke_result_t compile time syntax error

I'm creating a function that takes an iterable (a container) and its begin and end methods return iterator whose dereference can be modified by a passed lambda. Its sounds complicated, but I'm trying to do something like Python's super neat

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

code:

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

desired usage:

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

I don't want to hardcode uint64_t in the invoke_result in IteratorWrapper::operator* . It should be the return type of operator* in the base class (that is the templated type Iterator ).

But replacing the hardcoded header with the commented out return type gives me a compile error. The new header:

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

errors:

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:

What do you expect typename Iterator::operator* to yield? A type? A function pointer? A type of a function pointer?

There is no member type named operator* . There may be a function named that way. Do you mean taking it's return type to feed std::invoke_result_t ?

If so, that would be:

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

But you can shorten it with a simple declval:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM