需要有关在gcc-7.2.0中编译错误但在gcc-6.4.0中没有编译错误的代码的帮助

时间:2017-12-12 17:56:49

标签: c++ templates gcc c++14 variadic-templates

我有一段代码在gcc-6.4.0中编译并运行没有问题。 但是,在gcc-7.2.0中,相同的代码会出现以下编译错误:

gcc-7.2.0/bin/g++ -std=c++14 myerr.cc
myerr.cc: In lambda function:
myerr.cc:53:52: error: binary expression in operand of fold-expression
             tq_.push_back([&](){ return (dep->run<F, Args&&...>)(std::forward<F>(f), std::forward<Args>(args)...); });
myerr.cc:53:52: error: expected primary-expression before ‘,’ token
             tq_.push_back([&](){ return (dep->run<F, Args&&...>)(std::forward<F>(f), std::forward<Args>(args)...); });
                                                    ^
myerr.cc:53:58: error: expected primary-expression before ‘&&’ token
             tq_.push_back([&](){ return (dep->run<F, Args&&...>)(std::forward<F>(f), std::forward<Args>(args)...); });
                                                          ^~
myerr.cc:53:52: error: binary expression in operand of fold-expression
             tq_.push_back([&](){ return (dep->run<F, Args&&...>)(std::forward<F>(f), std::forward<Args>(args)...); });
                                          ~~~~~~~~~~^~~~~~
myerr.cc:53:63: error: mismatched operator in fold-expression before ‘>’ token
             tq_.push_back([&](){ return (dep->run<F, Args&&...>)(std::forward<F>(f), std::forward<Args>(args)...); });
                                                           ^
myerr.cc:53:63: error: expected ‘)’ before ‘>’ token

任何人都可以请求帮助解决错误消息吗?代码如下。

#include <iostream>
#include <deque>
#include <unordered_map>
#include <vector>
#include <utility>
#include <memory>
#include <functional>

template <typename T>
struct Task_Trait {
    typedef T obj_t;
    typedef T* obj_ptr;

    using pfid_t = const char * (T::*)() const;
    static pfid_t GetId;
};


template <typename T>
struct Task {
    typedef Task<T> task_t;
    typedef task_t * task_ptr;
    typedef std::unordered_map<std::string, std::unique_ptr<task_t>> taskmap_t;

private:    
    T *  obj_;
    std::vector<task_ptr> dependents_;

    Task(T& obj) : obj_(&obj), dependents_() {
    }

    static taskmap_t gtaskmap_;
    static std::deque<std::function<void()>> tq_;

public:
    static Task & CreateTask(T& obj) {
        static const char * (T::*getId)() const = Task_Trait<T>::GetId;
        const char * id = (obj.*getId)();
        auto it = gtaskmap_.find(id);
        if (it == gtaskmap_.end()) {
            it = gtaskmap_.emplace(id, std::move(std::unique_ptr<task_t>(new Task(obj)))).first;
        }
        return *(it->second);
    }

    template <typename F, class ... Args>
    void run(F&& f, Args&& ... args) {
        std::cout << "INFO: running function for task" << this->getId() << std::endl;
        (this->obj_->*f)(std::forward<Args>(args)...);
        for (auto dep : this->dependents_) {
            //auto mfunc = &(Task<T>::run<P>);
            tq_.push_back([&](){ return (dep->run<F, Args&&...>)(std::forward<F>(f), std::forward<Args>(args)...); });
        }
        while (!tq_.empty()) {
            std::function<void()> task = std::move(this->tq_.front());
            this->tq_.pop_front();
            task();
        }
    }

    const char * getId() const {
        static typename Task_Trait<T>::pfid_t getId = Task_Trait<T>::GetId;
        return (this->obj_->*getId)();
    }

    void depend(const char * id) {
        static typename Task_Trait<T>::pfid_t getId = Task_Trait<T>::GetId;
        auto dit = gtaskmap_.find(id);
        if (dit != gtaskmap_.end()) {
            dependents_.push_back(dit->second.get());
            std::cout << "INFO: " << id << " depends on " << this->getId() << std::endl;
        } else {
            std::cout << "ERROR: cannot find dependent " << id << " for task " << this->getId() << std::endl;
        }
    }
};


class DataTask {
public:
    DataTask(const char * id) : id_(id) {
    }

    void print(int x) {
        std::cout << "id=" << id_ << " value=" << x << std::endl;
    }

    const char * id() const {
        return id_.c_str();
    }

private:
    std::string id_;
};

template <typename T>
typename Task<T>::taskmap_t Task<T>::gtaskmap_;

template <typename T>
typename std::deque<std::function<void()>> Task<T>::tq_;

template <>
Task_Trait<DataTask>::pfid_t Task_Trait<DataTask>::GetId = &DataTask::id;

int main() {
    DataTask a("a");
    DataTask b("b");
    DataTask c("c");
    DataTask d("d");
    DataTask e("e");

    auto & ta = Task<DataTask>::CreateTask(a);
    auto & tb = Task<DataTask>::CreateTask(b);
    auto & tc = Task<DataTask>::CreateTask(c);
    auto & td = Task<DataTask>::CreateTask(d);
    auto & te = Task<DataTask>::CreateTask(e);

    ta.depend("b");
    ta.depend("c");
    tb.depend("d");
    tb.depend("e");

    return 0;
}

1 个答案:

答案 0 :(得分:1)

尝试在template中添加run()run()之前)。

我的意思是

// ...............................vvvvvvvvv
tq_.push_back([&](){ return (dep->template run<F, Args&&...>)(std::forward<F>(f), std::forward<Args>(args)...); });