1. 程式人生 > >c++ 11 遊記 之 decltype constexpr

c++ 11 遊記 之 decltype constexpr

script hide line variable pan sig 結果 roc .net

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 我覺得最好資料之中的一個

c++ 11 遊記 之 decltype constexpr