Gui*_*e07 6 c++ rvalue-reference c++11
template<typename T>
class BlockingQueue
{
std::queue<T> container_;
template< typename U >
void push(U&& value)
{
static_assert(std::is_same<T, typename std::remove_reference<U>::type>::value,"Can't call push without the same parameter as template parameter's class");
container_.push(std::forward<U>(value));
}
};
Run Code Online (Sandbox Code Playgroud)
我想BlockingQueue :: push方法能够处理类型为T的对象的rvalue和lvalue引用,以将其转发到 std::queue::push
正确的版本.是不是喜欢上面的代码,或者在我的BlockingQueue
类中提供两个版本的push方法?一个用于左值,一个用于右值
实施对我来说似乎是正确的,并且完成了工作.
然而,在你的情况下,为左值和右值提供不同的实现可能是一个好主意.(我能想到的)主要原因是扣除模板类型参数不适用于braced-init-lists.考虑:
struct foo {
foo(std::initializer_list<int>) {
}
};
// ...
foo f{1, 2, 3}; // OK
BlockingQueue<foo> b;
Run Code Online (Sandbox Code Playgroud)
使用OP的代码(*)
b.push(f); // OK
b.push({1, 2, 3}); // Error
Run Code Online (Sandbox Code Playgroud)
相反,如果BlockingQueue::push
提供以下重载:
void push(const T& value) {
container_.push(value);
}
void push(T&& value) {
container_.push(std::move(value));
}
Run Code Online (Sandbox Code Playgroud)
然后,以前失败的行将正常工作.
相同的参数适用于聚合.例如,如果foo
被定义为
struct foo {
int a, b, c;
};
Run Code Online (Sandbox Code Playgroud)
人们会观察到上述相同的行为.
我的结论是,如果你想BlockingQueue
支持更多类型(包括带有构造函数的聚合或类型std::initializer_list
),那么最好提供两个不同的重载.
(*)OP代码中的一个小修正:在static_assert
你需要使用的时候typename
typename std::remove_reference<U>::type>::value
^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
520 次 |
最近记录: |