1.背景
エラーのプログラミングの良い例の後に268ページのC ++入門に読み込むときに見つけました。
#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.基本的な知識(スキップ可能)
- 定数式。値は変更されませんし、表現のコンパイルプロセスで結果を得ることができるようになります。
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の変数。変数は、constexprのでなければなりません宣言した定数、および定数式で初期化する必要があります。
constexpr int mf = 20;
constexpr int limit = mf + 1;
const int *p1 = nullptr; //p1是指向常量的指针
int * const p2; //p2本身是常量
constexpr int *p3 = nullptr; // p3本身也是常量
-
リテラルタイプ。算術型、リテラルの型を関係の参照とポインタ、カスタムクラス、IOライブラリ、文字列型は、型リテラルに属していません。宣言constexprのにのみ、リテラルタイプ。
-
constexprの機能。この関数は定数式のために使用することができます。戻り値の型とパラメータの型のすべての機能は、文字通りの種類、機能、および本体のみがreturn文を持っている必要があります。constexprの機能は、必ずしも一定の式を返しません。
constexpr int new_sz() {return 42;}
constexpr int foo= new_sz();
-
クラス重合。次の条件がクラスであれば、クラスは、クラスの重合である:すべてのメンバーは、公開されません。すべてのコンストラクタを定義しない;ないクラス初期化子内、何の基底クラスと仮想関数。
-
リテラルクラス。以下は、すべてのリテラル条件のクラスがある以外のデータメンバーの高分子リテラル定数クラスのリテラルのタイプは、クラスされている:データメンバのタイプはリテラルであり、constexprのクラスは、少なくとも1つのコンストラクタを含める必要があります。もし初期値のクラスのデータメンバーを含むことは、ビルトイン型メンバの初期値は定数式でなければならない、またはクラスタイプに属する一部のメンバーならば、メンバーの初期値は、それ自体が使用されるコンストラクタをconstexprのでなければならず、デフォルトのクラスのデストラクタを使用する必要があります。定義、オブジェクトクラスの破壊のための責任ある一員。
3.分析します
- 例えば、io_subによって見られるとPRODであるconstexprの変数。従ってio_sub及びPROD自体は一定のタイプに、対応するデバッグCONST。
//constexpr Debug等价于 const Debug
constexpr Debug io_sub(false, true, false);
constexpr Debug prod(false);
- メンバ関数は、任意の()関数は、constexprのです。C ++ 11標準では、constexprの機能は、14標準C ++で、constexprの機能は、一定のメンバ関数ではない、constメンバ関数です。私のコンパイラのデフォルトのconstexprの機能は、一定のメンバ関数ではありません。
constexpr bool any()
//c++11标准下等价于
bool any () const
//c++14标准下等价于
bool any()
- この、)(任意のメンバ関数を呼び出す=&io_sub io_sub場合定数オブジェクト。このタイプは、デバッグにデバッグ* constのポイントである、とio_subはconstのDedugです。ポインタ型は、一般的にコールエラーので、それが指すオブジェクトの型と一致する必要があります。同じことが真PRODです。
io_sub.any()
prod.any()
4.修正
constexprの機能、下のC ++標準のデフォルトは一定のメンバ関数ではない、とio_subとPRODは一定のオブジェクトなので、あなただけのconstメンバ関数を呼び出すことができます。次の二つの方法を変更するには、任意の()constメンバ関数にすることもできます。
- constメンバ関数を作った後、任意の()constはプラスで。
constexpr bool any() const
{
return hw | io | other;
}
- 使用C ++ 11標準のコンパイル時には、デフォルトのconstexprの機能は、constメンバ関数です。
5.まとめ
- 変数は、constexprのは一定でなければならないと宣言しました。
- constexprの関数としてクラス内で宣言必ずしも標準C ++コンパイラによって決定される一定のメンバ関数ではありません。ときに彼らのニーズへのconstを追加するための最良の構想に従って、プログラミング。
- コンストラクタは、一定のメンバ関数であることはできないが、リテラルクラスのコンストラクタは、constexprの関数とすることができます。