gpt4 book ai didi

c++ - 通用引用 : Cannot convert parameter from 'int' to 'int &&'

转载 作者:太空狗 更新时间:2023-10-29 20:35:49 24 4
gpt4 key购买 nike

我在 VS 2015 社区版中运行以下所有代码。

当我尝试实现在 Code Review 中向我建议的建议时,我的代码出现错误.我遇到问题的部分是将 TryPush 的参数更改为 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 的 blog post 印象深刻TryPush(T && val) 是一个通用引用,我应该能够按照第一个代码片段中所示使用它,然后将值移动到数组中,从而确保代码无论是否正常工作将左值或右值传递给函数。如果它是面向公众的 Push 方法,它似乎会起作用,因此我对发生的事情有点困惑。我一定在这里遗漏了一些东西,想知道是否有人可以澄清它到底是什么。谢谢。

编辑像这样调用

RingBuffer<int> r(50);
for (int i = 0; i < 20; i++) {
r.Push(i + 1);
}

最佳答案

您的代码中没有通用引用。在blog post你链接,看到这个类似的例子:

template <class T, class Allocator = allocator<T> >
class vector {
public:
...
void push_back(T&& x); // fully specified parameter type ⇒ no type deduction;
... // && ≡ rvalue reference
};

要使用此代码,您需要编写类似 vector<int> v; v.push_back(x); 的内容,并且该函数已知为取 int&&所以没有扣除。

通用引用仅在从参数推导模板类型时发生(并且它们起作用是因为该类型可以推导为引用类型)。


如果您更改 TryPush(val),您的原始代码(具有按值传递)可以正常工作至 TryPush(std::move(val)) .为了消除不必要的移动操作,您可以提供两个重载,例如:

    void Push(T && val)     { while (!TryPush(std::move(val))); }
void Push(T const& val) { while (!TryPush(val)); }
private:
template<typename U>
bool TryPush(U&& val)
{
// preparation logic...
_ring_buffer_array[current_write] = std::forward<U>(val);

你当然可以使用两个重载 T const &T&&而不是 TryPush 的通用引用,但是你会在两个机构之间有一些代码重复。

您甚至可以替换 Push与:

template<typename U>
void Push(U&& val)
{
while ( !TryPush(std::forward<U>(val)) );
}

关于c++ - 通用引用 : Cannot convert parameter from 'int' to 'int &&' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40853487/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com