Namespaces
Variants

explicit specifier

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
explicit (C++11)
static

Special member functions
Templates
Miscellaneous

目次

翻訳内容: - "Contents" → "目次" - その他のテキスト(Syntax, Notes, Keywords, Example, See also)はC++関連の用語として翻訳せずに保持 - HTMLタグ、属性、構造は完全に保持 - 番号付けや書式は元のまま維持

構文

explicit (1)
explicit ( expression ) (2) (C++20以降)
expression - bool の文脈的に変換された定数式


1) コンストラクタ または変換関数 (C++11以降) または 推論ガイド (C++17以降) がexplicitであることを指定します。つまり、 暗黙変換 コピー初期化 に使用できません。
2) explicit 指定子は定数式と共に使用できる。その定数式が true と評価される場合に限り、関数はexplicitとなる。
(C++20以降)

explicit指定子は、コンストラクタ decl-specifier-seq の宣言内でのみ使用でき、 または変換関数 (C++11以降) のクラス定義内でのみ使用できます。

注記

単一の非デフォルトパラメータを持つコンストラクタ (C++11以前) (until C++11) explicit 関数指定子なしで宣言されている場合、 変換コンストラクタ と呼ばれます。

コピー コンストラクタ / ムーブコンストラクタ 以外のコンストラクタと、ユーザー定義変換関数は関数テンプレートとして定義可能です; explicit の意味は変わりません。

( トークンが explicit に続く場合、常にexplicit指定子の一部として解析されます:

struct S
{
    explicit (S)(const S&);    // error in C++20, OK in C++17
    explicit (operator int)(); // error in C++20, OK in C++17
};
(C++20以降)
機能テストマクロ 規格 機能
__cpp_conditional_explicit 201806L (C++20) 条件付き explicit

キーワード

explicit

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 は直接初期化を実行
    [](...){}(a4, a5, na1, na2, b5, nb2); // 「未使用変数」警告を抑制
}

関連項目