我正在使用VS 2015社区版运行以下所有代码。
当我尝试实施Code Review中建议我的建议时,我的代码出现错误。我遇到问题的部分是将参数更改为TryPush(T&& val)
。
#pragma once
#include <atomic>
#include <memory>
template <typename T> class RingBuffer {
public:
/*
Other functions
*/
void Push(T val) {
while (!TryPush(val));
}
private:
/*
Other functions
*/
//Private Member Functions
bool TryPush(T && val) {
const std::size_t current_write = write_position.load(std::memory_order_acquire);
const std::size_t current_read = read_position.load(std::memory_order_acquire);
const std::size_t next_write = increment_index(current_write);
if (next_write == current_read) { return false; }
_ring_buffer_array[current_write] = std::move(val);
write_position.store(next_write, std::memory_order_release);
return true;
}
std::size_t increment_index(std::size_t index) {
return (index + 1) % _buffer_capacity;
}
//Private Member Variables
std::atomic<std::size_t> read_position = 0;
std::atomic<std::size_t> write_position = 0;
std::size_t _buffer_capacity;
std::unique_ptr<T[], RingBufferFree> _ring_buffer_array;
};
每当我尝试编译这段代码时,都会出现以下错误:bool RingBuffer::TryPush(T &&)': cannot convert argument 1 from 'int' to 'int &&。令我困惑的是,如果我将代码更改为
#pragma once
#include <atomic>
#include <memory>
template <typename T> class RingBuffer {
public:
/*
Other functions
*/
void Push(T && val) {
while (!TryPush(val));
}
private:
/*
Other functions
*/
//Private Member Functions
bool TryPush(T val) {
const std::size_t current_write = write_position.load(std::memory_order_acquire);
const std::size_t current_read = read_position.load(std::memory_order_acquire);
const std::size_t next_write = increment_index(current_write);
if (next_write == current_read) { return false; }
_ring_buffer_array[current_write] = std::move(val);
write_position.store(next_write, std::memory_order_release);
return true;
}
std::size_t increment_index(std::size_t index) {
return (index + 1) % _buffer_capacity;
}
//Private Member Variables
std::atomic<std::size_t> read_position = 0;
std::atomic<std::size_t> write_position = 0;
std::size_t _buffer_capacity;
std::unique_ptr<T[], RingBufferFree> _ring_buffer_array;
};
它编译并运行。我从Scott Meyer的博客文章中得出的印象是
TryPush(T && val)
是一个通用引用,我应该能够像第一个代码片段中所示那样使用它,然后将值移动到数组中,从而确保代码能够正常工作,无论传递给函数的是左值还是右值。如果它是公共的Push
方法,它似乎可以工作,因此我有点困惑发生了什么。我一定是漏掉了什么,想知道是否有人能够澄清具体情况。谢谢。
编辑
这样调用。RingBuffer<int> r(50);
for (int i = 0; i < 20; i++) {
r.Push(i + 1);
}
TryPush
函数? - NathanOliver