C++ auto

C语言时代auto是栈上的自动变量的意思。如果没书写,默认就是auto

auto int i;  //C语言。等价于 int i;

C++11开始后,auto被引入了。上述语句就是非法的,因为auto有自动推导类型的意思,此时就不能手动指定类型了。

int a;
int& refa=a;
auto b = refa; // b的类型是int,不是int&

C++的auto推导,b被推导为int。如果我们想让b的类型与初始化表达式的类型一致,auto将不能胜任。

不管是auto b = expr; auto& b = expr;auto&& b = expr;...不管怎么写,都不能每次都让b的类型恰好等于expr表达式的类型。(有相等的情况)

只有引入decltype关键字后,提取和书写expr表达式类型才称为可能。代码如下:

decltype(1 + 2 + 3)  c1 = 1 + 2 + 3;  //c1类型是1+2+3的类型

int a = 10;
int& refa = a;

decltype(a) c0 = a;        //c0类型等于a的类型,等于int
decltype(refa) c1 = refa; //c1类型等于refa类型,等于int&

decltype(1+2+3) c1 = 1+2+3;  比较书写繁琐,  C++17引入了decltype(auto). 可以理解为,编译器为我们把其中的auto替换为expr

decltype(auto) c1 = 1 + 2 + 3;
//被替换成(隐含的自动扩展代码)
decltype(1 + 2 + 3) c1 = 1 + 2 + 3;

decltype(auto)可应用于模板函数返回值。代码如下:

template <typename T1, typename T2>
decltype(t1 + t2) add_fail_(T1 t1, T2 t2)   
//因编译器工作方式,无法成立
{
    return t1 + t2;
}

template <typename T1, typename T2>
auto add(T1 t1, T2 t2) -> decltype(t1 + t2)    //OK
{
    return t1 + t2;
}

//或者

template <typename T1, typename T2>
decltype(auto) add3(T1 t1, T2 t2)    //OK
{
    return t1 + t2;
}

auto可用于结构化绑定,例如:

struct S {
    int i;
    float j;
    bool k;
};

int main() {

    int a[3]{ 1,2,3 };

    //auto [x, y, z] = a; //等价于 int x = a[0]; int y = a[1]; int z = a[2];
    auto& [x, y, z] = a;  //等价于 int& x = a[0]; int& y = a[1]; int& z = a[2];
    x = 10;

    S s{ 1,2.0,true };
    auto& [x, y, z] = s; //等价于 int& x = s.i; int& y = s.j; int& z = s.k;
    x = 10;
}

auto用于lamda表达式:

int main() {
    auto lambda = [](int& x) { x += 3; };
    std::vector<int> vec{ 1,2,3,4,5,6,7 };
    std::for_each(vec.begin(), vec.end(), lambda);
}

auto用于template<auto > 。考虑如下应用,在MPL实践中,需要采取int2type技术,就是把文字常量类型化。代码如下:

template<int n>
struct typlized_int{
    using T = int;
    constexpr static int data = n;
};

template<short n>
struct typlized_short{
    using T = short;
    constexpr static short data = n;
};

template<char n>
struct typlized_char{
    using T = char;
    constexpr static char data = n;
};

int main()
{   
      std::cout << typlized_int<5>::data;
}

我们发现了可以合并的冗余代码,typlized_xxx很相似。就改造成:

template<typename T ,T n>
struct typlized{
    constexpr static T data = n;
};

int main()
{   
    std::cout << typlized<int,5>::data;
    std::cout << typlized<char,'a'>::data;
}

非常好,代码冗余大大的减少。但是还有个问题,typlized<char,'a'>中的char和‘5’是不是很冗余?能否让编译器根据‘a’自动推导出char呢?

答案是有的,在C++17中,可以这样写:

template<auto n>
struct typlized{
    constexpr static decltype(n) data = n;
};

int main()
{   
    std::cout << typlized<5>::data;
    std::cout << typlized<'a'>::data;
}

推导成功!这就是template<auto>.

原文链接: https://www.cnblogs.com/thomas76/p/8541086.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C++ auto

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/397582

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月11日 上午9:16
下一篇 2023年4月11日 上午9:16

相关推荐