c++类型推导

传统c和c++中,无论什么变量都应该先去声明其类型,指出其类型后才能进行下一步操作,这通常会花费很多无意义的时间。

c++11引入了auto 和 decltype 这两个关键字实现了类型推导,让编译器来操心变量的类型。这使得 C++ 也具有了和其他现代编程语言一样,某种意义上提供了无需操心变量类型的使用习惯。

auto

auto关键字可以对一些变量进行类型推导,简单使用样例如下:

int a=10;
auto b=a;

我们经常在对迭代器或循环中的变量声明中使用它,如

set<int> a;
... for(auto it
= a.begin();it != a.end();++it){...} vector<int>b; ... for(auto num:b){...}

auto的类型推导几乎和模板类型推导一致,除了一种特殊情况,即对花括号的推导。

auto test={1,2,3};  //test被推导为std::initializer_list<int>

template<typename T>
func(T type)
{
...
}

func({1,2,3});    //错误,无法推导出T的类型

有关auto的类型推导(与模板推导相同)需注意以下几点:

如果auto不是引用类型(即只用auto推导,而非auto&或auto&&),那么推导会忽略推导对象的引用部分和对自身的const或volatile修饰。

int x1=1;
const int x2=1;
int& x3=x1;
const char* const x4 = "test";

auto t1=x1;    //t1类型为int
auto t2=x2;    //t2类型为int
auto t3=x3;    //t3类型为int
auto t4=x4;    //t4类型为const char*

vs2022运行结果:

t1-t3通过以上规则容易理解,对于t4,x4是一个指向const char的指针常量,对于x4来说,其自身的常量性修饰是第二个const,即第二个const限制了其自身值无法改变,因此类型推导会忽略第二个const,最终推导出t4的类型为const char*

对于auto& 和auto&& ,详见万能引用文章

 

decltype

decltype关键字可以对一些表达式类型进行推导,例如:

auto x=1;    //x被推导为int
auto y=2;
decltype(x+y) z;    //z被推导为int
if (std::is_same<decltype(x), int>::value)
    std::cout << "type x == int" << std::endl;    //对x的类型进行判断

尾返回类型推导

c++11支持对函数返回类型进行推导,方法如下所示:

template<typename T, typename U>
auto add2(T x, U y) -> decltype(x+y){
    return x + y;
}

我们甚至可以配合std::future访问异步操作结果来实现对函数类型的推导(线程池中常见):

template <typename F, typename... Args>
    auto submit(F&& f, Args&&... args) -> std::future<decltype(std::forward<F>(f)(std::forward<Args>(args)...))>
    {
        using return_type = decltype(f(args...));
        auto task_ptr = std::make_shared<std::packaged_task<return_type()>>(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
        auto task_future = task_ptr->get_future();
        auto wrapper_func = [task_ptr]() { (*task_ptr)(); };
        schedule_by_id(std::move(wrapper_func));
        return task_future;
    }

注意上述函数返回的是一个std::future对象即期约对象,对返回对象使用get方法即可获取函数 f 即decltype(std::forward<F>(f)(std::forward<Args>(args)...))类型的结果。

在c++14中支持直接auto推导返回值类型,无需尾返回推导。

posted @ 2023-04-03 19:45  _Explosion!  阅读(67)  评论(0编辑  收藏  举报