c++ - 模板化 std::future 返回问题

标签 c++ templates linker std

我使用 C++11 创建了一个线程池类,如下所示。

#include <iostream>
#include <functional>
#include <vector>
#include <condition_variable>
#include <thread>
#include <mutex>
#include <queue>
#include <atomic>
#include <future>

class threadpool {
    struct task {
        std::size_t m_priority;
        std::function<void()> m_fn;
        bool operator()(task* t1, task* t2) const {
            return t1->m_priority < t2->m_priority;
        }
    };
public:
    threadpool(std::size_t nthreads);
    ~threadpool();
    // void assign(std::function<void()> fn, std::size_t priority);
    template <typename T> std::future<T> assign(std::function<T()> fn, std::size_t priority);
private:
    void funnel();
    std::vector<std::thread*> m_threadlist;
    std::priority_queue<task*, std::vector<task*>, task> m_tasks;
    std::mutex m_tasks_mtx;
    std::condition_variable m_newc;
    std::mutex m_newc_mtx;
    std::atomic<bool> m_destruct;
};
threadpool::threadpool(std::size_t nthreads) {
    for (std::size_t _n = nthreads; _n > 0; --_n)
        m_threadlist.push_back(new std::thread(std::bind(&threadpool::funnel, this)));
}
threadpool::~threadpool() {
    m_destruct = true;
    while (!m_threadlist.empty()) {
        m_newc.notify_one();
    }
}

/* ... */

template <typename T>
std::future<T> assign(std::function<T()> fn, std::size_t priority) {
    std::promise<T> _prom;
    std::future<T> _ft = _prom.get_future();
    threadpool::task* _t = new task();
    _t->m_fn = std::bind([](std::promise<T>& p) {
        p.set_value(fn());
    }, std::ref(_prom));
    _t->m_priority = priority;
    {
        std::lock_guard<std::mutex> _lock(m_tasks_mtx);
        m_tasks.push(_t);
    }
    m_newc.notify_one();
    return _ft;
}
void threadpool::funnel() {
    while (!m_destruct) {
        {
            std::unique_lock<std::mutex> _lock(this->m_newc_mtx);
            m_newc.wait(_lock);
        }
        for (;;) {
            threadpool::task* _t;
            {
                std::lock_guard<std::mutex> _lock(m_tasks_mtx);
                if (m_tasks.empty()) break;
                _t = m_tasks.top();
                m_tasks.pop();
            }
            _t->m_fn();
            delete _t;
        }
    }
}
int count() {
    return 3;
}
int main(int argc, char* argv[])
{
    threadpool* herppool = new threadpool(10);
    for(int i = 0; i<900;i++) {
        auto derp = herppool->assign<int>(count,3); // <-- error here
        //printf("%d", derp.get());
    }
    delete herppool;
    //getchar();
}

我无法解决为什么我在 MSVC 2012 下的指定行出现以下错误。

1>  main.cpp
1>main.obj : error LNK2001: unresolved external symbol "public: class std::future<int> __thiscall threadpool::assign<int>(class std::function<int __cdecl(void)>,unsigned int)" (??$assign@H@threadpool@@QAE?AV?$future@H@std@@V?$function@$$A6AHXZ@2@I@Z)
1>C:\Users\...\visual studio 2012\Projects\threadpool\Release\threadpool.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

在我看来,该功能似乎存在。我不知道链接器在提示什么,非常感谢您提供一些帮助来追踪错误。我已经盯着它看了几个小时了。

最佳答案

如果你仔细看这里:

template <typename T>
std::future<T> assign(std::function<T()> fn, std::size_t priority)

您没有定义threadpool::assign,而是一个名为assign 的自由函数。链接器非常清楚地告诉您您忘记定义 threadpool::assign。你需要这样:

template <typename T>
std::future<T> threadpool::assign(std::function<T()> fn, std::size_t priority)

关于c++ - 模板化 std::future 返回问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14018256/

相关文章:

c++ - 类中析构函数定义的 Collect2 错误

c++ - 否定 size_t (即 `-sizeof(struct foo)` ))会发生什么?

c++ - 如何将 RTF 格式转换为 HTML

c++ - 候选模板被忽略 : couldn't infer template argument

c++ - 类模板 : Prevent assignment of <other> type

gcc - 如何通过 gcc 的确切名称链接库?

c++ - 如何获取在 Main.cpp 中声明的全局变量以便在 header 中访问

c++ - 从纯虚拟模板类派生

c - 初学者编写makefile;检查我的 Makefile

c++ - CMake 链接不是子文件夹