c++ 11 游记 之 decltype constexpr

title: c++ 11 游记 1
keyword :c++ 11 decltype constexpr


作者:titer1 zhangyu
出处:www.drysaltery.com
联系:1307316一九六八(仅接受短信)
声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|Creative Commons BY-NC-ND 3.0 ,转载请注明作者及出处。
tips for image: http://7xjs3n.com1.z0.glb.clouddn.com


c++ 11 游记 1(decltype constexpr)

一. 结缘 decltype

参考source

上code

#include <iostream>

struct A {
   double x;
};
const A* a = new A();

decltype( a->x ) x3;       // type of x3 is double (declared type)
decltype((a->x)) x4 = x3;  // type of x4 is const double& (lvalue expression)

template <class T, class U>
auto add(T t, U u) -> decltype(t + u); // return type depends on template parameters

int main() 
{
    int i = 33;
    decltype(i) j = i*2;

    std::cout << "i = " << i << ", "
              << "j = " << j << '\n';

    auto f = [](int a, int b) -> int {
       return a*b;
    };

    decltype(f) f2{f}; // the type of a lambda function is unique and unnamed
    i = f(2, 2);
    j = f2(3, 3);

    std::cout << "i = " << i << ", "
              << "j = " << j << '\n';
}

初步心得

此论要点:
- 初步掌握四种情形,详细看代码
- 函数后置的返回类型
- 变量(无括号的)申明
- 变量(有括号的)申明
- 和Lamda表达式相关
-
- 需要注意的是,如果一个对象的名称加上括号,它成为左值表达式

  • 他还是lamda表达式的好基友喔!
    decltype is useful when declaring types that are difficult or impossible to declare using standard notation, like lambda-related types or types that depend on template parameters.

尝试难点

If expression is a function call which returns a prvalue of class type or is a comma expression whose right operand is such a function call, a temporary object is not introduced for that prvalue. The class type need not be complete or have an available destructor. This rule doesn’t apply to sub-expressions:in decltype(f(g())), g() must have a complete type, but f() need not.

debug情况

我试着改变lamda表达式中的参数,但是编译器提示我,不能通过,原因待查明

二. constexpr

  • 首先了解字面值 LiteralType,常用语字符串

  • 可以在编译时期被动地计算表达式的值

  • constexpr 将编译期常量概念延伸至括用户自定义常量以及常量函数,其值的不可修改性由编译器保证,因而constexpr 表达式是一般化的,受保证的常量表达式
    比const 前置修饰的函数 的能力 更广

code from csdn

    enum Flags { good=0, fail=1, bad=2, eof=4 };

    constexpr int operator|(Flags f1, Flags f2)
    { return Flags(int(f1)|int(f2)); }

    void f(Flags x)
    {
        switch (x) {
        case bad:         /* … */ break;
        case eof:         /* … */ break;
        case bad|eof:     /* … */ break;
        default:          /* … */ break;
        }
    }

      constexpr int x1 = bad|eof;    // ok

    void f(Flags f3)
    {
        // 错误:因为f3不是常量,所以无法在编译时期计算这个表达式的结果值
        constexpr int x2 = bad|f3;
        int x3 = bad|f3;     // ok,可以在运行时计算
    }

code from cpp.com

#include <iostream>
#include <stdexcept>

// The C++11 constexpr functions use recursion rather than iteration
// (C++14 constexpr functions may use local variables and loops)
constexpr int factorial(int n)
{
    return n <= 1 ? 1 : (n * factorial(n-1));
}

// literal class
class conststr {
    const char * p;
    std::size_t sz;
 public:
    template<std::size_t N>
    constexpr conststr(const char(&a)[N]) : p(a), sz(N-1) {}
    // constexpr functions signal errors by throwing exceptions
    // in C++11, they must do so from the conditional operator ?:
    constexpr char operator[](std::size_t n) const {
        return n < sz ? p[n] : throw std::out_of_range("");
    }
    constexpr std::size_t size() const { return sz; }
};

// C++11 constexpr functions had to put everything in a single return statement
// (C++14 doesn't have that requirement)
constexpr std::size_t countlower(conststr s, std::size_t n = 0,
                                             std::size_t c = 0) {
    return n == s.size() ? c :
           s[n] >= 'a' && s[n] <= 'z' ? countlower(s, n+1, c+1) :
           countlower(s, n+1, c);
}

// output function that requires a compile-time constant, for testing
template<int n> struct constN {
    constN() { std::cout << n << '\n'; }
};

int main()
{
    std::cout << "4! = " ;
    constN<factorial(4)> out1; // computed at compile time

    volatile int k = 8; // disallow optimization using volatile
    std::cout << k << "! = " << factorial(k) << '\n'; // computed at run time

    std::cout << "Number of lowercase letters in \"Hello, world!\" is ";
    constN<countlower("Hello, world!")> out2; // implicitly converted to conststr
}

心得

  • 迭代函数的值 在编译期间计算得到!!!!!
  • 还有就是下图,详细如下:

三.其他:好资料

scott meyer 讲cpp11

C++11 FAQ中文版:常量表达式(constexpr)
cpp 我认为最好资料之一

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值