提问人:Leon 提问时间:4/18/2023 最后编辑:halferLeon 更新时间:5/1/2023 访问量:124
如何完美地转发一个通用引用,要么是常量引用,要么是可移动的右值?
How to perfectly forward a universal reference that is either a const ref or a movable rvalue?
问:
我已经用 C++20 编写了一个无锁和线程安全的环队列,到目前为止它有效。唯一不完美的是它必须有两个方法,一个接受对左值的常量引用作为参数,另一个接受对右值的引用,以便将右值移动到队列中而不是再次构造。enque()
代码的先前版本如下,只是一个框架,需要简化:
template <typename T>
class RingQue_t {
public:
explicit RingQue_t( size_t capacity );
~RingQue_t();
bool deque( T& dest_ ) { return true; };
// If we offer a const ref, the compiler will select this one
bool enque( const T& src_ ) {
// a lot of same codes goes here for a same logic...
new( _buff + _tail ) T( src_ );
};
// If we offer a rvalue ref, the compiler will select this one
bool enque( T& src_ ) {
// a lot of same codes goes here for a same logic...
new( _buff + _tail ) T( std::move( src_ ) );
};
protected:
T* _buff = nullptr;
};
我正在尝试将这两种方法合并为一种方法,并且已经阅读了一些文档和示例,但我仍然无法正确使用它。
这是我的期望:std::forward
template <typename T>
class RingQue_t {
public:
template<typename U>
bool enque( U&& src_ ) {
// new( _buff + _tail ) T( src_ );
// new( _buff + _tail ) T( std::move( src_ ) );
// new( _buff + _tail ) T( std::forward<T>( src_ ) );
std::allocator<T> allc;
allc.construct( _buff + _tail, std::forward<T>( src_ ) );
return true;
};
};
// testing
const std::string s0 { "s0" };
RingQue_t<std::string> str_que( 16 );
str_que.enque( std::string { "s1" } ); // works
str_que.enque( s0 ); // can not pass the compiling.
评论中的所有解决方案都已尝试过,但没有一个有效。我总是收到错误消息:
将类型“std::remove_referencestd::__cxx11::basic_string<char >::type&”{aka 'std::__cxx11::basic_string&'} 绑定到“const std::__cxx11::basic_string”的引用丢弃限定符
正确的使用方法是什么?std::forward
答:
6赞
Cosemuckel
4/18/2023
#1
proplem 与事实有关,这不能正确地转发论点的恒常性。这是因为被推导出为 ,但是在使用此常量转发后就丢失了。为了解决这个问题,只需将enque()
U
const T&
std::forward<T>()
std::forward<T>()
std::forward<U>()
另请注意,在 中已弃用,而是使用std::allocator<T>::construct
c++17
std::allocator_traits::construct
评论
0赞
user17732522
4/18/2023
"在 C++17 中已弃用“:并在 C++ 20 中删除。所以它甚至不会再编译了。
评论
forward
std::forward<T>( src_ )
->std::forward<U>( src_ )
bool enque( T& src_ )
T
const
bool enque(T&& src_)