504b吧 关注:32贴子:1,430
  • 9回复贴,共1
c艹是世界上最好(艹)的语言


IP属地:北京1楼2017-04-18 06:08回复
    linux下用了c++11的代码,cmakelist里一般会用cmakecheckflag检查找到的编译器是否支持-std=c++11这个flag
    但是如果想在win上用msvc编译同样的代码,首先你mkdir build && cd build ,跑cmake .. 。
    找编译器阶段正常应该会找一个叫cl.exe的东西
    然后跑到cmake_cxx_check_flag这地儿,问题来了。这个返回值有可能是不正确的(true和false都有可能。电脑重启一遍返回值就不一样了你怕不怕)
    懒比解决方法是不checkflags了,在cmake里删掉与这相关的代码。反正cl默认直接支持c++11
    终极解决办法是用mingw编译。去他妈的msvc


    IP属地:北京2楼2017-04-18 06:40
    回复
      #include <iostream>
      class A{public: A() {} /*explicit*/ A(int n) { c = n; }
      char c;};
      void f(A a) { std::cout << a.c; }
      int main(){ A a; a = 70; f(80); std::cout << a.c;}
      这个可以编译。运行输出PF。(没毛病
      在构造函数前把explicit关键字加上就不能编译了


      IP属地:北京3楼2017-04-18 06:49
      回复
        template <class T>class A{public: template <class U> void f() {}};
        template <class T>void g(){ A<T> a; a.template f<int>();}
        int main(){ g<int>();}
        这个能编译。但是如果把函数g()里的a.template f<int>(); 写成a.f<int>();就不行了。不很懂
        qtcreator调用模板函数不自动补全。对象后面加个.template就又能补全了。不很懂


        IP属地:北京4楼2017-04-18 07:08
        回复
          -Wl,--no-as-needed
          想链接一个静态库以及链接pthread,编译器参数不加这个能正常编译,但是运行会报错。不很懂


          IP属地:北京5楼2017-04-18 07:13
          回复
            std::bind是函数指针的完美(?)替代品


            IP属地:北京6楼2017-04-18 07:25
            回复
              /** * @brief This class manages multiple threads and fills them with work. */class ThreadPool{ public: /// \brief Constructor. Launches some amount of workers. /// \param[in] numThreads The number of threads in the pool. ThreadPool(size_t numThreads);
              /// \brief Destructor. This joins all threads. ~ThreadPool();
              /// \brief Enqueue work for the thread pool /// /// Pass in a function and its arguments to enqueue work in the thread pool /// \param[in] function A function pointer to be called by a thread. /// \param args Function arguments. /// \returns A std::future that will return the result of calling function. /// If this function is called after the thread pool has been stopped, /// it will return an uninitialized future that will return /// future.valid() == false template<class Function, class ... Args> std::future<typename std::result_of<Function(Args...)>::type> enqueue(Function&& function, Args&&... args);
              /// \brief Stop the thread pool. This method is non-blocking. void stop() { stop_ = true; }
              /// \brief This method blocks until the queue is empty. void waitForEmptyQueue() const; private: /// \brief Run a single thread. void run(); /// Need to keep track of threads so we can join them. std::vector<std::thread> workers_; /// The task queue. std::queue<std::function<void()>> tasks_; /// A mutex to protect the list of tasks. mutable std::mutex tasks_mutex_; /// A condition variable for worker threads. mutable std::condition_variable tasks_condition_; /// A condition variable to support waitForEmptyQueue(). mutable std::condition_variable wait_condition_; /// A counter of active threads unsigned active_threads_; /// A signal to stop the threads. volatile bool stop_;};
              // Enqueue work for the thread pool.template<class Function, class ... Args>std::future<typename std::result_of<Function(Args...)>::type> ThreadPool::enqueue( Function&& function, Args&&... args){ typedef typename std::result_of<Function(Args...)>::type return_type; // Don't allow enqueueing after stopping the pool. if (stop_) { LOG(ERROR)<< "enqueue() called on stopped ThreadPool"; // An empty future will return valid() == false. return std::future<typename std::result_of<Function(Args...)>::type>(); }
              auto task = std::make_shared<std::packaged_task<return_type()>>( std::bind(std::forward<Function>(function), std::forward<Args>(args)...));
              std::future<return_type> res = task->get_future(); { std::unique_lock<std::mutex> lock(tasks_mutex_); tasks_.push([task]() {(*task)();}); } tasks_condition_.notify_one(); return res;}
              // The constructor just launches some amount of workers.ThreadPool::ThreadPool(size_t threads) : active_threads_(0), stop_(false){ for (size_t i = 0; i < threads; ++i) workers_.emplace_back(std::bind(&ThreadPool::run, this));}
              // Destructor. This joins all threads.ThreadPool::~ThreadPool(){ { std::unique_lock<std::mutex> lock(tasks_mutex_); stop_ = true; } tasks_condition_.notify_all(); for (size_t i = 0; i < workers_.size(); ++i) { workers_[i].join(); }}
              // Run a single thread.void ThreadPool::run(){ while (true) { std::unique_lock<std::mutex> lock(this->tasks_mutex_); while (!this->stop_ && this->tasks_.empty()) { this->tasks_condition_.wait(lock); } if (this->stop_ && this->tasks_.empty()) { return; } std::function<void()> task(this->tasks_.front()); this->tasks_.pop(); ++active_threads_; // Unlock the queue while we execute the task. lock.unlock(); task(); lock.lock(); --active_threads_; // This is the secret to making the waitForEmptyQueue() function work. // After finishing a task, notify that this work is done. wait_condition_.notify_all(); }}
              // This method blocks until the queue is empty.void ThreadPool::waitForEmptyQueue() const{ std::unique_lock<std::mutex> lock(this->tasks_mutex_); // Only exit if all tasks are complete by tracking the number of // active threads. while (active_threads_ || !tasks_.empty()) { this->wait_condition_.wait(lock); }}


              IP属地:北京7楼2017-04-23 16:13
              收起回复
                shared_ptr
                这东西的实现比当初想象中要复杂得多
                原理太长不写了
                总之
                他是线程安全的
                更重要的是,最好不要用传统指针去构造它,尽管它确实允许你这么做
                正常应该std::shared_ptr<A> p(new A());
                如果你A *p1 = new A(); std::shared_ptr<A> p2(p1);
                p2的控制块里保存的引用计数仍然为1
                如果你某处有一行delete p1; 这个对象被析构1次
                如果没有其他拷贝,p2作用域结束后,这个对象也被析构1次
                这样一共就析构了2次
                就糟了


                IP属地:北京8楼2017-04-25 03:34
                回复
                  stl里的map数据结构内部是个二叉树。自定义的类型也能作为key,但是必须实现比较器(重载小于号)
                  忘了你就会被报一屏编译错误
                  c++11有了unordered_map,它是hash表,所以自定义类型做key必须定义hash_value函数并重载==
                  忘了你就会被报一屏编译错误


                  IP属地:北京9楼2017-05-02 16:48
                  回复
                    被多线程数据同步问题艹哭


                    IP属地:北京10楼2017-06-02 14:25
                    回复