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;
}
2. Basic knowledge (skippable)
- 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()结果未知
- 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本身也是常量
-
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.
-
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();
-
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.
-
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
- 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);
- 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()
- 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:
- In any () const plus after making const member functions.
constexpr bool any() const
{
return hw | io | other;
}
- Use c ++ 11 standard compile time, is the default constexpr function is const member functions.
5. Summary
- Variables declared constexpr must be a constant.
- 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.
- A constructor can not be a constant member functions, but literals class constructor can be constexpr function.