C++併發編程(附錄A)[ constexpr-04]


author:

  • luixiao1223
    title: 附錄A

A.4 constexpr functions

const

const int i=23;
const int two_i=i*2;
const int four=4;
const int forty_two=two_i-four;
  1. Specify the bounds of an array:

    int bounds=99;
    int array[bounds]; //Error
    const int bounds2=99;
    int array2[bounds2];
    
  2. Specify the value of a nontype template parameter

    template<unsigned size>
    struct test
    {};
    test<bounds> ia; // Error
    test<bounds2> ia2;
    
  3. Provide an initializer for a static const class data member of
    integral type in the class definition:

    class X {
        static const int the_answer=forty_two;
    };
    
  4. Provide an initializer for a built-in type or aggregate that can be
    used for static initialization:

    struct my_aggregate
    {
        int a;
        int b;
    };
    static my_aggregate ma1={forty_two,123};
    int dummy=257;
    static my_aggregate ma2={dummy,dummy};
    
  5. Static initialization like this can be used to avoid
    order-of-initialization problems and race conditions.

constexpr 是一個函數修飾符

constexpr int square(int x)
{
    return x*x; 
}
int array[square(5)];

int dummy=4;
int array[square(dummy)]; //Error dummy is not a constant 

constexpr and user-defined types

literal type

  1. It must have a trivial copy constructor.
  2. It must have a trivial destructor.
  3. All non-static data members and base classes must be trivial types.
  4. It must have either a trivial default constructor or a constexpr
    constructor other than the copy constructor.
constexpr CX create_cx()
{
    return CX();
}
//or
constexpr CX clone(CX val)
{
    return val;
}
  1. C++11 a constexpr function can only call other constexpr functions.
  2. C++14 you can do almost anything in a constexpr function, provided
    it doesn’t modify any objects with non-local scope

C++11也可以做的事情, 給成員函數添加 constexpr 屬性

class CX
{
private:
    int a;
    int b;
public:
    CX() = default;
    constexpr CX(int a_, int b_):
        a(a_),b(b_)
    {}
    constexpr int get_a() const
    {
            return a;
    }
    constexpr int get_b() // C++11 意味着是const函數.但是C++14就不一定了.
    {
        return b;
    }
    constexpr int foo()
    {
        return a+b;
    }
};

關於 get_b C++11 意味着是const函數.但是C++14就不一定了.
你可以做下面的事情.

constexpr CX make_cx(int a)
{
    return CX(a,1);
}
constexpr CX half_double(CX old)
{
    return CX(old.get_a()/2,old.get_b()*2); }
constexpr int foo_squared(CX val)
{
    return square(val.foo());
}
int array[foo_squared(half_double(make_cx(10)))];

The key benefit of constant expressions and constexpr functions
involving user-defined types is that objects of a literal type
initialized with a constant expression are statically initialized, and
so their initialization is free from race conditions and initialization
order issues:

CX si=half_double(CX(42,19)); //Statically initialized

NOTE:If the constructor is declared constexpr and the con- structor
parameters are constant expressions, the initialization is constant
initialization and happens as part of the static initialization phase.
This is one of the most important changes in C++11 as far as concurrency
goes.you can avoid any race conditions over their ini- tialization,
because they’re guaranteed to be initialized before any code is run.

聲明在global區的mutex,
atomic就是.因爲要用它來同步線程.所以它就需要早於所有的代碼先初始化.而它的構造函數正是
constexpr.

constexpr objects

主要是 診斷 用.可以判斷一個對象可不可以進行靜態初始化.

constexpr int i=45; // OK
constexpr std::string s(“hello”); // Error, string 不可以靜態初始化
int foo();
constexpr int j=foo(); // Error 不可以.

constexpr function requirements

C++11

  1. All parameters must be of a literal type.
  2. The return type must be a literal type.
  3. The function body must consist of a single return statement.
  4. The expression in the return statement must qualify as a constant
    expression.
  5. Any constructor or conversion operator used to construct the return
    value from the expression must be constexpr.

C++14

  1. Multiple return statements are allowed.
  2. Objects created within the function can be modified.
  3. Loops, conditionals, and switch statements are allowed.

*成員函數*

  1. constexpr member functions can’t be virtual.
  2. The class for which the function is a member must be a literal type.

*構造函數*

  1. The constructor body must be empty for a C++11 compiler; for a C++14
    or later compiler it must satisfy the requirements for a constexpr
    function.
  2. Every base class must be initialized.
  3. Every non-static data member must be initialized.
  4. Any expressions used in the member initialization list must qualify
    as constant expressions.
  5. The constructors chosen for the initialization of the data members
    and base classes must be constexpr constructors.
  6. Any constructor or conversion operator used to construct the data
    members and base classes from their corresponding initialization
    expression must be constexpr.

This is the same set of rules as for functions, except that there’s no
return value, so no return statement. Instead, the constructor
initializes all the bases and data members in the member initialization
list. Trivial copy constructors are implicitly constexpr.

constexpr and templates

template<typename T>
constexpr T sum(T a,T b)
{
  return a+b; 
}
constexpr int i=sum(3,42); //OK, constexpr
std::string s=sum(std::string("hello"),std::string(" world")); //OK,但是不是constexpr
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章