C ++ Primer: literals error class calls the function (the book P268 example given)


1. Background

  Found when reading to C ++ Primer on page 268 after good examples of programming error.

#include <iostream>
using namespace std;
class Debug
{
public:
    constexpr Debug(bool b = true) : hw(b), io(b), other(b){};
    constexpr Debug(bool h, bool i, bool o) : hw(h), io(i), other(o){};
    constexpr bool any()
    {
        return hw | io | other;
    }
    void set_io(bool b)
    {
        io = b;
    }
    void set_hw(bool b)
    {
        hw = b;
    }
    void set_other(bool b)
    {
        other = b;
    }

private:
    bool hw;
    bool io;
    bool other;
};

int main()
{
    constexpr Debug io_sub(false, true, false);
    if(io_sub.any())
    {
        cerr << "print approptiate error messages" << endl;
    }
    constexpr Debug prod(false);
    if(prod.any())
    {
        cerr << "print an error message" << endl;
    }
    return 0;
}

Error prompt

2. Basic knowledge (skippable)

  1. Constant expression . Value will not change and will be able to get results in the compilation process of expression.
const int max_files = 20; // max_files是常量表达式
const int limit = max_files + 1; // limit是常量表达式
int staff_size=27; // staff_size不是常量表达式,因为staff_size不是常量
const int sz = get_size(); // sz不是常量表达式,因为get_size()结果未知
  1. constexpr variables . Variables declared constexpr must be a constant , and must be initialized with constant expressions.
constexpr int mf = 20;
constexpr int limit = mf + 1;
const int *p1 = nullptr; //p1是指向常量的指针
int * const p2; //p2本身是常量
constexpr int *p3 = nullptr; // p3本身也是常量
  1. Literal type . Arithmetic types, references and pointers pertaining literal types, custom classes, the IO library, string type does not belong to the type literal. Only literal type to declare constexpr.

  2. constexpr function . Function can be used for constant expressions. The return type and a function of all of the parameter types are literal types, functions, and only the body must have a return statement. constexpr function does not necessarily return a constant expression.

constexpr int new_sz() {return 42;}
constexpr int foo= new_sz();
  1. Class polymerization . When the following conditions are a class, the class is Class polymerization: All members are public; not define any constructor; not within the class initializer; no base classes and virtual functions.

  2. Literals class . Data members are literal types of polymeric literal constant class is class, except the following is the class of all literals conditions: the type of data members are literal; constexpr class must contain at least one constructor; if a containing the class data members of the initial value, the initial value of the built-type members must be a constant expression, or if some members belonging to a class type, the initial value of the members themselves must be used constructor constexpr; must use the default class destructor definition, the member responsible for the destruction of the object class.

3. Analyze

  1. Seen by the example, io_sub and prod is constexpr variable . Therefore io_sub and prod itself is a constant , which corresponds to the type const the Debug .
//constexpr Debug等价于 const Debug 
constexpr Debug io_sub(false, true, false);
constexpr Debug prod(false);
  1. Member function any () function is a constexpr. In c ++ 11 standard, constexpr function is const member functions, in 14 standard c ++, constexpr function is not a constant member functions. My compiler default constexpr function is not a constant member functions.
constexpr bool any()
//c++11标准下等价于
bool any () const
//c++14标准下等价于
bool any()
  1. When the constant object io_sub calling the member function any (), this = & io_sub. This type is Debug * const, point to Debug, and io_sub is const Dedug. Pointer type generally must match the type of the object it points to, so call error. The same is true prod.
io_sub.any()
prod.any()

4. Correction

  Since the c ++ standard default under, constexpr function is not a constant member functions, and io_sub and prod are constant objects, you can only call const member functions. It can be any () const member functions to modify the following two ways:

  1. In any () const plus after making const member functions.
constexpr bool any() const
{
	return hw | io | other;
}

operation result

  1. Use c ++ 11 standard compile time, is the default constexpr function is const member functions.

operation result

5. Summary

  1. Variables declared constexpr must be a constant.
  2. Declared in the class as a function of constexpr it is not necessarily constant member function, which is determined by the standard c ++ compiler. When programming, according to their needs the best initiative to add const.
  3. A constructor can not be a constant member functions, but literals class constructor can be constexpr function.
Published 77 original articles · won praise 25 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_34801642/article/details/104634709