简体   繁体   English

我可以确定右值引用的类型吗?

[英]Can I determine the type of an rvalue reference?

I have a serialize function that performs differently based on the type.我有一个序列化 function,它根据类型执行不同的操作。 I'd like to be able to call it with both f(x) and f(5) , but f(5) fails with error No matching function for call to 'f', Candidate function [with T = int] not viable: expects an l-value for 1st argument.我希望能够同时使用f(x)f(5)来调用它,但是f(5)失败并出现错误No matching function for call to 'f', Candidate function [with T = int] not viable: expects an l-value for 1st argument. If I change f(T& t) to f(T&& t) then f(x) is not arithmetic.如果我将f(T& t)更改为f(T&& t) ,则f(x)不是算术。 How can I recognize both f(x) and f(5) to be arithmetic, and similarly for any type such as the string type below?我怎样才能将f(x)f(5)都识别为算术运算,并且对于任何类型(例如下面的字符串类型)也是如此? I don't want to force the input to be const because I want to alter it otherwise.我不想强制输入为 const,因为我想以其他方式更改它。

template<typename T>
void f(T& t)
{
    if constexpr (std::is_arithmetic_v<T>)
    {
        // do stuff
    }
    else if constexpr (std::is_same_v<T, std::string>)
    {
        // do other stuff
    }
    else
    {
        //alter non-const input
    }
}

int main()
{
    int x;
    f(x);
    f(5);
    return 0;
}

You can use a forwarding reference, T&& , to take the argument by either lvalue- or rvalue reference depending on what's passed in.您可以使用转发引用T&&来根据传入的内容通过左值或右值引用获取参数。

In case of lvalue, T = int& , so we need to use std::decay_t to remove the reference from the type.在左值的情况下, T = int& ,所以我们需要使用std::decay_t从类型中删除引用。

When we pass an rvalue, T = int and decay does nothing.当我们传递一个右值时, T = int并且 decay 什么都不做。

#include <type_traits>
#include <string>
#include <iostream>

template<typename T>
void f(T&& t)
{
    using T_Type = std::decay_t<T>; // remove const/reference from the type
    if constexpr (std::is_arithmetic_v<T_Type>)
    {
        // do stuff
    }
    else if constexpr (std::is_same_v<T_Type, std::string>)
    {
        // do other stuff
    }
    else
    {
        //alter non-const input
    }
}

int main()
{
    int x;
    f(x);
    f(5);
    return 0;
}

Note that std::decay performs请注意, std::decay执行

Applies lvalue-to-rvalue, array-to-pointer, and function-to-pointer implicit conversions to the type T将左值到右值、数组到指针和函数到指针的隐式转换应用于类型 T

If any of those cases is not desired, you can use a combination of std::remove_reference and std::remove_const , or in case of c++20 we can use std::remove_cvref .如果不需要任何这些情况,您可以结合使用std::remove_referencestd::remove_const ,或者在 c++20 的情况下我们可以使用std::remove_cvref

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM