std :: remove_reference解释了吗? [英] std::remove_reference explained?

查看:52
本文介绍了std :: remove_reference解释了吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到了 std :: remove_reference 如下

I saw possible implementations for std::remove_reference as below

template< class T > struct remove_reference      {typedef T type;};
template< class T > struct remove_reference<T&>  {typedef T type;};
template< class T > struct remove_reference<T&&> {typedef T type;};   

为什么对 lvalue rvalue参考有专门的说明?通用模板本身不足以删除参考吗?我在这里感到困惑,因为在 T& T&& 专业化中,如果我尝试使用 :: type ,我仍然应该得到 T& T&& 正确吗?

Why is it that there are specializations for lvalue and rvalue reference? Won't the general template itself be sufficient and remove the reference? I'm confused here because in the T& or T&& specialization if I try to use ::type I should still get T& or T&& respectively right?

您能否解释一下,为什么我们在移动时强制转换为 remove_reference< t> :: type&&?(是因为参数已命名,所以将其视为move函数中的左值?).

Could you explain how, why we cast to remove_reference<t>::type&& in move? (is it because that the parameter is named so it will be treated as an lvalue inside the move function?).

此外,您能指出一种找出并打印出什么类型的方法的方法吗?例如,如果其类型为 int rvalue ,那么我应该能够打印出已通过 int&& 的信息?(我一直在使用 std :: is_same 进行手动检查.)

Also, could you point out a way whereby I can find out and print what the type is? for e.g if its an rvalue of type int then I should be able to print out that int&& was passed? (I've been using std::is_same to check but manually.)

谢谢您的时间.

推荐答案

为什么左值和右值引用有专门的专业知识?

why is it that there are specializations for lvalue and rvalue reference?

如果仅存在主模板,则执行以下操作:

If only the primary template existed, then doing:

remove_reference<int&>::type

会给你:

int&

并且正在做

remove_reference<int&&>::type

会给你:

int&&

这不是您想要的.左值引用和右值引用的特殊化允许从传递的类型参数中分别剥离& & .

Which is not what you want. The specializations for lvalue references and rvalue references allow stripping the & and the &&, respectively, from the type argument you pass.

例如,如果您正在做

remove_reference<int&&>

类型 int&& 将匹配由 T&& 专业化指定的模式,其中 T int.由于专业化将类型别名 type 定义为 T (在本例中为 int ),因此请执行以下操作:

The type int&& will match the pattern specified by the T&& specialization, with T being int. Since the specialization defines the type alias type to be T (in this case, int), doing:

remove_reference<int&&>::type

会给你 int .

您能解释为什么,为什么我们在 move 中强制转换为 remove_reference< t> :: type& 吗?

这是因为如果 move()的定义如下:

That's because if move() were defined as follows:

    template<typename T>
    T&& move(T&& t) { ... }
//  ^^^
//  Resolves to X& if T is X& (which is the case if the input has type X
//  and is an lvalue)

然后,如果 move()的参数是 X 类型的左值,则返回类型将为 X& (这就是-称为通用引用").我们要确保返回类型始终是右值引用.

Then the return type will be X& if the argument of move() is an lvalue of type X (that's how so-called "universal references"). We want to make sure that the return type is always an rvalue reference.

move()的目的是使您返回右值,无论您在输入中传递了什么.由于函数调用的函数的返回类型是右值引用是右值,因此我们确实希望 move()始终返回右值引用.

The purpose of move() is to give you back an rvalue, no matter what you pass in input. Since a function call for a function whose return type is an rvalue reference is an rvalue, we really want move() to always return an rvalue reference.

这就是为什么我们要执行 remove_reference< T> :: type&& ,因为始终保证将&& 附加到非引用类型可以保证生成一个右值引用类型.

That's why we do remove_reference<T>::type&&, because appending && to a non-reference type is always guaranteed to yield an rvalue reference type.

您还能指出一种方法,让我找出并打印出类型吗?

Also could you point out a way whereby I can find out and print what the type is?

我不确定您在这里所说的打印"是什么意思.我不知道将类型的名称转换为字符串的便携式方法(无论如何获取该类型).

I'm not sure what you mean by "print" here. There is no portable way I know of converting the name of a type to a string (no matter how you obtain that type).

另一方面,如果您的目标是确保传递了右值,则可以使用静态断言,如下所示:

If your goal is to make sure that an rvalue was passed, on the other hand, you could use a static assertion like so:

#include <type_traits>

template<typename T>
void foo(T&&)
{
    static_assert(!std::is_reference<T>::value, "Error: lvalue was passed!");
    // ...
}

这取决于以下事实:当传递类型为 X 的左值时,将推导出 T X& .

Which relies on the fact that when an lvalue of type X is being passed, T will be deduced to be X&.

如果只想产生替换失败,也可以使用等效的SFINAE约束:

You could also use an equivalent SFINAE-constraint, if you only want to produce a substitution failure:

#include <type_traits>

template<typename T, typename std::enable_if<
    !std::is_reference<T>::value>::type* = nullptr>
void foo(T&&)
{
    // ...
}

这篇关于std :: remove_reference解释了吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆