身份功能,完美转发
Identity function with perfect forwarding
我想编写一个函数identity
它完美地转发其参数而无需任何副本。我会写这样的东西
template< typename V >
inline V&& identity( V&& v )
{
return std::forward< V >( v );
}
但这是正确的吗?它是否始终返回正确的类型?如果是左值/左值引用/临时,它是否只是独立地转发v
?
您可以使用参数包作为保护,这样没有人可以实际强制使用与否则推导的类型不同的类型。
举一个最小的工作示例:
#include <type_traits>
#include <utility>
template<typename..., typename V>
constexpr V&& identity(V&& v) {
return std::forward<V>(v);
}
int main() {
static_assert(std::is_same<decltype(identity(42)), int&&>::value, "!");
static_assert(std::is_same<decltype(identity<int>(42)), int&&>::value, "!");
static_assert(std::is_same<decltype(identity<float>(42)), int&&>::value, "!");
// here is the example mentioned by @Jarod42 in the comments to the question
static_assert(std::is_same<decltype(identity<const int &>(42)), int&&>::value, "!");
}
这样,返回类型取决于 v
参数的实际类型,并且您不能以任何方式强制复制。
正如@bolov的评论中提到的,语法可能很快就会变得晦涩难懂。
无论如何,正如@Jarod42所建议的那样,这是一个更明确地说明我们正在做的事情的问题。
举个例子:
template <typename... EmptyPack, typename V, typename = std::enable_if_t<sizeof...(EmptyPack) == 0>>
作为替代方案:
template <typename... EmptyPack, typename V, std::enable_if_t<sizeof...(EmptyPack) == 0>* = nullptr>
甚至:
template <typename... EmptyPack, typename V>
constexpr
std::enable_if_t<sizeof...(EmptyPack) == 0, V&&>
identity(V&& v) {
return std::forward<V>(v);
}
选择您喜欢的一个并使用它,在这种情况下它们应该都是有效的。
相关文章:
- 将函数参数完美转发到函数指针:按值传递呢?
- C++20理念:要求表达和完美转发
- 完美的转发和构造函数
- 我可以列表初始化 std::vector 并完美转发元素吗?
- 返回值的完美转发?
- 使用衰减与完美转发
- 可变参数模板:将整数参数完美转发到 lambda
- 完美转发C++重载和模板化函子及其参数
- 在完美转发中需要衰减
- C++完美转发:如何避免悬空引用
- 完美的对象转发阵列
- 无法理解一段具有完美转发和省略号的C++代码
- 在编写包装现有函数并检查错误的模板函数时,如何使用完美转发?
- 完美转发可变参数模板模板
- 在完美转发函数中公开参数类型,避免代码重复
- 完美的转发构造函数和已删除的构造函数
- 完美的转发功能推断出冲突错误
- 使用完美转发的模板转换构造函数
- 完美转发使用结构化绑定声明的变量
- 完美转发常量参数以进行持续评估