std:forward 在模板类中
std:forward inside a template class
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));
}
};
我希望 BlockingQueue::p ush 方法能够处理 T 类型的对象的 rvalue 和 lvalue 引用,以将其转发到正确的版本std::queue::push
。最好像上面的代码一样做,还是在我的BlockingQueue
类中提供两个版本的推送方法?一个用于左值,一个用于右值
实现对我来说
似乎是正确的,并且可以完成工作。
不过,在您的情况下,为左值和右值提供不同的实现可能是一个好主意。主要原因(我能想到的)是模板类型参数的推导不适用于大括号初始化列表。考虑:
struct foo {
foo(std::initializer_list<int>) {
}
};
// ...
foo f{1, 2, 3}; // OK
BlockingQueue<foo> b;
使用OP的代码(*)
b.push(f); // OK
b.push({1, 2, 3}); // Error
如果相反,则提供以下BlockingQueue::push
重载:
void push(const T& value) {
container_.push(value);
}
void push(T&& value) {
container_.push(std::move(value));
}
然后,曾经失败的行将正常工作。
相同的参数适用于聚合。例如,如果foo
被定义为
struct foo {
int a, b, c;
};
人们会观察到上述相同的行为。
我的结论是,如果您希望BlockingQueue
支持更多类型(包括集合或构造函数采用 std::initializer_list
s 的类型),那么最好提供两种不同的重载。
(*) OP代码中的一个小更正:在static_assert
中你需要使用typename
typename std::remove_reference<U>::type>::value
^^^^^^^^
如果你想
使用完美的转发,那么我建议你使用emplace
queue
类的方法。 emplace
方法将给定的参数转发给构造函数T
。无需检查T
是否与U
相同。只要T
可以从U
构造,它就应该编译。此外,如果您愿意,您可以使用可变参数模板参数。
template<typename... Args>
void push(Args&&... args)
{
container_.emplace(std::forward<Args>(args)...);
}
因此,你可以推送任何你想要的东西,只要T是从给定的参数构造的。
相关文章:
- 完美前进使用 std::forward vs RefRefCast
- 你如何理解"std: :forward is just syntactic sugar"?这是真的吗?
- "std::forward"和"std::move"真的不生成代码吗?
- 在C++中使用 std::forward 的多个参数
- 如何使用 std::forward 精确地评估参数包的扩展?
- 普通的右值引用和 std::forward 返回的引用有什么区别?
- 怎么可能写 f( *this, std::forward<Args>(args)... ) 而 f 只用 F f 声明;
- 如何通过通用引用或std::forward将这三个c++模板函数合并为一个
- 自 C++11 年以来对 std::forward 实施的理解
- 当将参数包传递给另一个可变参数模板函数时,我是否必须使用 std::forward
- 为什么要在概念中使用std::forward
- 寻求对std::forward的澄清
- 为什么 std::forward 将左值和右值转换为右值引用?
- std::forward() 的右值引用重载的目的是什么?
- std::forward 如何推断出"_Ty"的类型?
- 没有匹配函数调用 std::forward(const std::string &) 与可变参数
- C++ decltype(auto) or decltype(std::<T>forward(value))?
- std::function operator() 和 std::forward 中发生了什么?
- How to std::forward( *this )
- 在哪些情况下,从 std::forward 分配比从 std::move 分配更可取?为什么