小编Ove*_*ade的帖子

移动操作后C++ lambda'this'指针失效

我在当前项目中有以下(简化)代码:

#include <iostream>
#include <string>
#include <functional>
#include <vector>


class Test{

public:

    Test() = default;
    Test(const Test& other) = delete;
    Test& operator=(const Test& other) = delete;
    Test(Test&& other) = default;
    Test& operator=(Test&& other) = default;



    void setFunction(){
       lambda = [this](){
           a = 2;
       };
    }  

    int callAndReturn(){
       lambda();
       return a;
    }

private:
    std::function<void()> lambda; 
    int a = 50;
};


int main()
{
  Test t;
  t.setFunction();
  std::vector<Test> elements;
  elements.push_back(std::move(t));
  std::cout << elements[0].callAndReturn() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

当我运行它时,打印值50而不是预期值2.我想这是因为lambda函数捕获当前this指针.在移动操作之后,this指针改变并且函数写入错误a …

c++ lambda move

10
推荐指数
1
解决办法
575
查看次数

enable_if和多个条件的问题

我试图实现一个将泛型类型转换为字符串的函数.积分类型需要使用std::to_string(),字符串和字符使用std::string()和矢量,逐个元素,使用其他方法之一(取决于其内容)转换为字符串.

这就是我所拥有的:

//Arithmetic types    

template<class T>
typename std::enable_if<std::is_arithmetic<T>::value, std::string>::type convertToString(const T& t){
    return std::to_string(t);
}

//Other types using string ctor

template<class T>
typename std::enable_if<std::__and_<std::__not_<std::is_arithmetic<T>>::type,
        std::__not_<std::is_same<T, <T,
       std::vector<typename T::value_type, typename T::allocator_type>>::value
       >>>::value, std::string>::type convertToString(const T& t){
    return std::string(t);
}

//Vectors

template<class T>
typename std::enable_if<std::is_same<T, std::vector<typename T::value_type, 
   typename T::allocator_type>>::value, std::string>::type convertToString(const T& t){
    std::string str;
    for(std::size_t i = 0; i < t.size(); i++){
        str += convertToString(t[i]);
    }
    return str;
}
Run Code Online (Sandbox Code Playgroud)

问题是第二个函数没有编译.如何设计第二个函数以便它编译(和工作)并且不会产生歧义问题?

c++ templates sfinae enable-if c++14

7
推荐指数
2
解决办法
4552
查看次数

C++20 线程可能永远等待 std::atomic

考虑以下示例代码,其中线程 A 将函数推送到队列中,线程 B 在从队列中弹出时执行这些函数:

std::atomic<uint32_t> itemCount;

//Executed by thread A
void run(std::function<void()> function) {

    if (queue.push(std::move(function))) {
        itemCount.fetch_add(1, std::memory_order_acq_rel);
        itemCount.notify_one();
    }

}


//Executed by thread B
void threadMain(){

    std::function<void()> function;

    while(true){

        if (queue.pop(function)) {

            itemCount.fetch_sub(1, std::memory_order_acq_rel);
            function();

        }else{
            itemCount.wait(0, std::memory_order_acquire);
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

其中queue是一个并发队列,它有一个push和一个pop函数,每个函数返回一个bool指示给定操作是否成功。所以如果满了就push返回,如果空就返回。falsepopfalse

现在我想知道代码是否在所有情况下都是线程安全的。假设线程 Bpop失败并且即将调用std::atomic<T>::wait. 同时,线程 A 推送一个新元素,而线程 B 检查初始等待条件。由于itemCount尚未更改,因此失败。

紧接着,线程 A 增加计数器并尝试通知一个正在等待的线程(尽管线程 B 尚未在内部等待)。线程 B 最终等待原子,导致线程由于丢失信号而永远不会再次醒来,尽管队列中有一个元素。只有当新元素被推入队列时才会停止,通知 …

c++ atomic wait stdatomic c++20

7
推荐指数
1
解决办法
1730
查看次数

标签 统计

c++ ×3

atomic ×1

c++14 ×1

c++20 ×1

enable-if ×1

lambda ×1

move ×1

sfinae ×1

stdatomic ×1

templates ×1

wait ×1