c++尾置返回类型和引用去除

场景

当我们在编写模板函数的时候,如果用户用显示模板实参表示返回类型是最好的
但是如果用户用的是泛型的话,会给用户增加额外负担
比如我们定义一个模板,传入vector<int>的迭代器,要求返回他所指向的值

尾置返回类型

我们可以用decltype来获取表达式的类型

template <typename It>
auto fcn2(It beg) -> decltype(*beg)
{
    return *beg;
}

这里的decltype为解引用运算符的左值,因此推断的类型是int&
和我们预期的int不符(而且因为是引用,用typeid也没法查)

引用类型去除

如果我们想要的是一个int值,那我们在定义类型的时候需要去掉这个引用
标准库提供了类型转换模板,可以用remove_reference去除引用

template <typename It>
auto fcn(It beg) -> typename remove_reference<decltype(*beg)>::type //type是该函数返回值的成员
{
    return *beg;
}

这样就可以将类型脱去引用了

测试代码

template <typename It>
auto fcn(It beg) -> typename remove_reference<decltype(*beg)>::type
{
    return *beg;
}

template <typename It>
auto fcn2(It beg) -> decltype(*beg)
{
    return *beg;
}

int main()
{
    vector<long> a = { 123, 11 };
    cout << &a[0] << endl;  //和下面的fcn2作对比
    cout << typeid(fcn2(a.begin())).name() << endl;  //在vs里,鼠标移到fcn2上会显示他返回结果是long&
    cout << fcn2(a.begin()) << endl;
    cout << &fcn2(a.begin()) << endl;  //这里是为了证明他是引用,所以输出地址

    cout << typeid(fcn(a.begin())).name() << endl;  //在vs里,鼠标移到fcn上会显示他返回结果是long
    cout << fcn(a.begin()) << endl;
    //cout << &fcn(a.begin()) << endl;  //这里编辑器直接报错,因为他不是左值
    auto pp = fcn(a.begin());
    cout << &pp << endl;
}
测试结果:
0123EC30
long
123
0123EC30
long
123
00B9FA04

其他模板方法

func_name<T> T func_name::type
remove_reference X& or X&& X
else T
add_const X& or const X or 函数 T
else const T
add_lvalue_reference X& T
X&& X&
else T&
add_rvalue_reference X& or X&& T
else T&&
remove_pointer X* X
else T
add_pointer X& or X&& X*
else T*
make_signed unsigned X X
else T
make_unsigned signed X unsigned X
else T
remove_extent X[n] X
else T
remove_all_extents X[n1][n2] X
else T

其他说明

上面提到的typeid,是一个输出变量类型的方法

#include <typeinfo> 
int a = 1;
char b = 'b';
int& c = a;
typeid(a).name(); //int
typeid(b).name(); //char
typeid(c).name(); //int
上一篇:C++ 语言 迭代器失效


下一篇:篮球联赛数据api示例