名前空間
変種
操作

explicit 指定子

提供: cppreference.com
< cpp‎ | language
 
 
C++言語
一般的なトピック
フロー制御
条件付き実行文
繰り返し文 (ループ)
ジャンプ文
関数
関数宣言
ラムダ関数宣言
inline 指定子
例外指定 (非推奨)
noexcept 指定子 (C++11)
例外
名前空間
指定子
decltype (C++11)
auto (C++11)
alignas (C++11)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点
文字 - 文字列 - nullptr (C++11)
ユーザ定義 (C++11)
ユーティリティ
属性 (C++11)
typedef 宣言
型エイリアス宣言 (C++11)
キャスト
暗黙の変換 - 明示的な変換
static_cast - dynamic_cast
const_cast - reinterpret_cast
メモリ確保
クラス
クラス固有の関数特性
explicit (C++11)
static
特別なメンバ関数
テンプレート
その他
 
 
explicit (1)
explicit ( expression ) (2) (C++20およびそれ以降)
expression - bool 型の文脈的に変換された定数式
1) コンストラクタまたは変換関数 (C++11およびそれ以降)が明示的である、つまり、暗黙の変換およびコピー初期化で使用できないことを指定します。
2) explicit 指定子は定数式と共に使用することもできます。 定数式が true に評価される場合、その関数は explicit になります。
(C++20およびそれ以降)

explicit 指定子はクラス定義内のコンストラクタまたは変換関数 (C++11およびそれ以降)の宣言の decl-specifier-seq にのみ現れることができます。

[編集] ノート

explicit 指定子なしで宣言された非デフォルト引数を1個持つ (C++11以前)コンストラクタは変換コンストラクタと呼ばれます。

(コピー/ムーブ以外の) コンストラクタとユーザ定義変換関数はどちらも、関数テンプレートであっても構いません。 explicit の意味は変わりません。

explicit に続く開き括弧トークンは explicit 指定子の一部として解析されます。

struct S {
    explicit (S)(const S&);    // C++20 ではエラー、 C++17 では OK。
    explicit (operator int)(); // C++20 ではエラー、 C++17 では OK。
};
(C++20およびそれ以降)

[編集]

struct A
{
    A(int) { }      // 変換コンストラクタ。
    A(int, int) { } // 変換コンストラクタ (C++11)。
    operator bool() const { return true; }
};
 
struct B
{
    explicit B(int) { }
    explicit B(int, int) { }
    explicit operator bool() const { return true; }
};
 
int main()
{
    A a1 = 1;      // OK、コピー初期化は A::A(int) を選択します。
    A a2(2);       // OK、直接初期化は A::A(int) を選択します。
    A a3 {4, 5};   // OK、直接リスト初期化は A::A(int, int) を選択します。
    A a4 = {4, 5}; // OK、コピーリスト初期化は A::A(int, int) を選択します。
    A a5 = (A)1;   // OK、明示的なキャストは static_cast を行います。
    if (a1) ;      // OK、A::operator bool()
    bool na1 = a1; // OK、コピー初期化は A::operator bool() を選択します。
    bool na2 = static_cast<bool>(a1); // OK、 static_cast は直接初期化を行います。
 
//  B b1 = 1;      // エラー、コピー初期化は B::B(int) を考慮しません。
    B b2(2);       // OK、直接初期化は B::B(int) を選択します。
    B b3 {4, 5};   // OK、直接初期化は B::B(int, int) を選択します。
//  B b4 = {4, 5}; // エラー、コピーリスト初期化は B::B(int,int) 考慮しません。
    B b5 = (B)1;   // OK、明示的なキャストは static_cast を行います。
    if (b2) ;      // OK、B::operator bool()
//  bool nb1 = b2; // エラー、コピー初期化は B::operator bool() を考慮しません。
    bool nb2 = static_cast<bool>(b2); // OK、 static_cast は直接初期化を行います。
}