略
この訳では、自然な日本語になるように、 規格としての意味が変わらない範囲で適宜文の構造を変えるなどしている。 例えば、長い文を2つに分ける、日本語として冗長な表現を排するなどのことをしている。
略
略
略
1 この文書は C++ プログラミング言語の処理系に対する要求を指定する。 第一の要求は処理系が言語を実装することであり、これはこの文書が C++ を定義するということを意味する。 その他の要求と、第一の要求の例外は、この文書の中で折に触れて述べる。
2 C++ は 「ISO/IEC 9899:2011 Programming languates -- C」(以降 C 規格と呼ぶ) によって定義される C 言語を元にした汎用の言語である。 C によって提供される機能の他に、C++ は追加のデータ型、クラス、テンプレート、例外、名前空間、 演算子と関数の多重定義、参照、メモリ管理の演算子、追加のライブラリ機能を提供する。
1 This document specifies requirements for implementations of the C++ programming language. The first such requirement is that they implement the language, so this document also defines C++ . Other requirements and relaxations of the first requirement appear at various places within this document.
2 C++ is a general purpose programming language based on the C programming language as described in ISO/IEC 9899:2011 Programming languages — C (hereinafter referred to as the C standard). In addition to the facilities provided by C, C ++ provides additional data types, classes, templates, exceptions, namespaces, operator overloading, function name overloading, references, free store management operators, and additional library facilities.
この部分は C++03 の時から更新されていない。 C++11 以降で追加されたメジャーな機能――例えばラムダ式などは追加しなくても良いのだろうか?
1 以下の文書は、その内容の一部または全ての内容がこの文書の要求を構成するものとして、この文書の本文から適宜参照される。 以下の文書で版が指定されている場合は、ここで参照した版のみが有効である。 版が指定されていない場合は、その文書の最新版 (訂正 (amendments) を含む) が有効である。
2 ISO/IEC 9899:2011 の Clause 7 で記述されるライブラリは、以降 C 標準ライブラリ (C standard library) と呼ぶ1。
3 ISO/IEC 9945:2003 で記述される OS のインターフェイスは、以降 POSIX と呼ぶ。
4 Ecma-262 標準で記述される ECMAScript 言語仕様は、以降 ECMA-262 と呼ぶ。
5 ISO/IEC 10967-1:2012 で記述される算術仕様は、以降 LIA-1 と呼ぶ。
footnote 1 C.5 の Clause 21 から 33 までの但し書き付きで、 C 標準ライブラリは C++ 標準ライブラリの部分集合である。
1 The following documents are referred to in the text in such a way that some or all of their content constitutes requirements of this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments) applies.
2 The library described in Clause 7 of ISO/IEC 9899:2011 is hereinafter called the C standard library1.
3 The operating system interface described in ISO/IEC 9945:2003 is hereinafter called POSIX.
4 The ECMAScript Language Specification described in Standard Ecma-262 is hereinafter called ECMA-262.
5 The arithmetic specification described in ISO/IEC 10967-1:2012 is hereinafter called LIA-1.
footnote 1 With the qualifications noted in Clauses 21 through 33 and in C.5, the C standard library is a subset of the C ++ standard library.
1 この文書の説明のため、 ISO/IEC 2382-1:1993 で与えられる用語と定義、 ISO 80000-2:2009 で与えられる用語と定義と記号、 更に次のものが適用される。
2 ISO と IEC は、標準規格で使うことを目的として用語のデータベースを次の URL で管理している。
3 Clause 20 から 33 と補遺 D で使用される追加の用語が、20.3 で定義される。
4 この文書の極一部で使われる用語は、その使用箇所で斜体で定義される。
1 For the purposes of this document, the terms and definitions given in ISO/IEC 2382-1:1993, the terms, definitions, and symbols given in ISO 80000-2:2009, and the following apply.
2 ISO and IEC maintain terminological databases for use in standardization at the following addresses:
3 20.3 defines additional terms that are used only in Clauses 20 through 33 and Annex D.
4 Terms that are used only in a small portion of this document are defined where they are used and italicized where they are defined.
《実行時の動作》 オブジェクトの値を読み取るか修正すること
〈execution-time action〉 to read or modify the value of an object
《関数呼び出し式》 丸括弧で囲まれたカンマ区切りのリストに含まれる式 (8.2.2)
〈function call expression〉 expression in the comma-separated list bounded by the parentheses (8.2.2)
《関数マクロ》 丸括弧で囲まれたカンマ区切りのリストに含まれるプリプロセッサトークンの列 (19.3)
〈function-like macro〉 sequence of preprocessing tokens in the comma-separated list bounded by the parentheses (19.3)
《例外スロー式》 throw
の対象 (8.17)
〈throw expression〉 the operand of throw
(8.17)
《テンプレート実体化》 角括弧で囲まれたカンマ区切りのリストに含まれる constant-expression、type-id、または id-expression (17.3)
〈template instantiation〉 constant-expression, type-id, or id-expression in the comma-separated list bounded by the angle brackets (17.3)
■16.3, 17.6, 17.8 のあと
1 同じスコープで一つの名前について2つ以上の宣言が指定された時、その名前は多重定義 (overload) されているという。 更に、同じスコープで同じ名前だが異なる型の二つの宣言を多重定義 (overloaded declaration) と呼ぶ。 関数および関数テンプレートの宣言のみが多重定義されうる。 つまり、変数と型の宣言は多重定義できない。
2 多重定義された関数名が呼び出しで使われた時、 関数の多重定義の内どれが用いられるかは、 実引数の型とその時点で可視の多重定義の仮引数の型を比較することによって決定される。 関数を選択する手続きは多重定義解決 (overload resolution) と呼び 16.3 で定義される。[例:
double abs(double); int abs(int); abs(1); // abs(int); が呼び出される abs(1.0); // abs(double); が呼び出される
- 例終わり ]
1 When two or more different declarations are specified for a single name in the same scope, that name is said to be overloaded. By extension, two declarations in the same scope that declare the same name but with different types are called overloaded declarations. Only function and function template declarations can be overloaded; variable and type declarations cannot be overloaded.
2 When an overloaded function name is used in a call, which overloaded function declaration is being referenced is determined by comparing the types of the arguments at the point of use with the types of the parameters in the overloaded declarations that are visible at the point of use. This function selection process is called overload resolution and is defined in 16.3. [Example:
double abs(double); int abs(int); abs(1); // calls abs(int); abs(1.0); // calls abs(double);
-- end example]
1 全ての関数宣言が多重定義できるわけではない。 多重定義できないものをここで指定する。 同じスコープに多重定義できない宣言の組を含むプログラムは不適格である。 [註: この制限は、そのスコープにおける明示的宣言同士、または明示宣言と using 宣言により導入される宣言の間に適用される。 (using 指令などに基づく) 名前解決や、 (演算子関数などの) 多重定義解決の過程で考慮される関数の集合に対しては適用されない。 - 註終わり ]
2 一部の関数宣言は多重定義できない:
class X { static void f(); void f(); // 不適格 void f() const; // 不適格 void f() const volatile; // 不適格 void g(); void g() const; // OK: 静的な g がないので void g() const volatile; // OK: 静的な g がないので };- 例終わり ]
class Y { void h() &; void h() const &; // OK void h() &&; // OK, 全ての宣言が ref 修飾子を持つ。 void i() &; void i() const; // 不適格。前の i の宣言は ref 修飾子を持つ。 };- 例終わり ]
1 Not all function declarations can be overloaded. Those that cannot be overloaded are specified here. A program is ill-formed if it contains two such non-overloadable declarations in the same scope. [Note: This restriction applies to explicit declarations in a scope, and between such declarations and declarations made through a using-declaration (10.3.3). It does not apply to sets of functions fabricated as a result of name lookup (e.g., because of using-directives) or overload resolution (e.g., for operator functions). - end note ]
2 Certain function declarations cannot be overloaded:
class X { static void f(); void f(); // ill-formed void f() const; // ill-formed void f() const volatile; // ill-formed void g(); void g() const; // OK: no static g void g() const volatile; // OK: no static g };—end example ]
class Y { void h() &; void h() const &; // OK void h() &&; // OK, all declarations have a ref-qualifier void i() &; void i() const; // ill-formed, prior declaration of i // has a ref-qualifier };—end example ]
3 [註: 11.3.5 で指定したように、関数宣言の組が等価な仮引数宣言を持つ場合、 これらは同じ関数を宣言することになるので多重定義することはできない。
typedef int Int; void f(int i); void f(Int i); // OK: f(int) の再宣言 void f(int i) { /* ... */ } void f(Int i) { /* ... */ } // error: f(int) の再定義- 例終わり ] 一方で列挙型は独立した型であり、関数の異なる多重定義を与える。 [例:
enum E { a }; void f(int i) { /* ... */ } void f(E i) { /* ... */ }- 例終わり ]
int f(char*); int f(char[]); // f(char*); と同じ int f(char[7]); // f(char*); と同じ int f(char[9]); // f(char*); と同じ int g(char(*)[10]); int g(char[5][10]); // g(char(*)[10]); と同じ int g(char[7][10]); // g(char(*)[10]); と同じ int g(char(*)[20]); // g(char(*)[10]); とは異なる。- 例終わり ]
void h(int()); void h(int (*)()); // h(int()) の再宣言 void h(int x()) { } // h(int()) の定義 void h(int (*x)()) { } // 不適格: h(int()) の再定義- 例終わり ]
typedef const int cInt; int f (int); int f (const int); // f(int) の再宣言 int f (int) { /* ... */ } // f(int) の定義 int f (cInt) { /* ... */ } // error: f(int) の再定義- 例終わり ] 仮引数型の一番外側の const/volatile 型指定子のみが、以下のように無視される。 仮引数型の内部に埋め込まれた const/volatile 型指定子は、 関数の多重定義を区別する上で意味を持つ123。 特に、任意の型
T
について、T
へのポインタ、
const T
へのポインタ、volatile T
へのポインタは、
異なる仮引数型と解釈される。
T
への参照、const T
への参照、
volatile T
への参照についても同様である。
void f (int i, int j); void f (int i, int j = 99); // OK: f(int, int) の再宣言 void f (int i = 88, int j); // OK: f(int, int) の再宣言 void f (); // OK: f の多重定義の宣言 void prog () { f (1, 2); // OK: f(int, int) の呼び出し f (1); // OK: f(int, int) の呼び出し f (); // Error: f(int, int) と f() のどちら? }- 例終わり ]
- 註終わり ]
footnote 123 仮引数型が関数型を含む場合 (例えば仮引数型が関数ポインタの場合)、 その内部関数型の仮引数型において最も外側の const/volatile 型指定子は無視される。
この部分は Note に過ぎないので細かいことは気にしていないのかもしれないが、色々と記述に穴がある気がする。 例えば、differs only として項目を連ねているが、2つ以上の項目で異なる場合については述べていないので語弊がある。 また、内部関数型の仮引数の const/volatile 無視については述べているが typedef/配列型/関数型 については述べていない。 実際のコンパイラで試すと、期待通り typedef/配列型/関数型 も考慮に入れられるようなので、これはここの記述が分かりにくいだけだ。 思うに、〈仮引数の宣言型〉・〈仮引数の調整型〉・〈型の同一性〉のような概念を導入して統一的に定義するべきなのではという気がする。
3 [Note: As specified in 11.3.5, function declarations that have equivalent parameter declarations declare the same function and therefore cannot be overloaded:
typedef int Int; void f(int i); void f(Int i); // OK: redeclaration of f(int) void f(int i) { /* ... */ } void f(Int i) { /* ... */ } // error: redefinition of f(int)—end example ] Enumerations, on the other hand, are distinct types and can be used to distinguish overloaded function declarations. [Example:
enum E { a }; void f(int i) { /* ... */ } void f(E i) { /* ... */ }—end example ]
int f(char*); int f(char[]); // same as f(char*); int f(char[7]); // same as f(char*); int f(char[9]); // same as f(char*); int g(char(*)[10]); int g(char[5][10]); // same as g(char(*)[10]); int g(char[7][10]); // same as g(char(*)[10]); int g(char(*)[20]); // different from g(char(*)[10]);—end example ]
void h(int()); void h(int (*)()); // redeclaration of h(int()) void h(int x()) { } // definition of h(int()) void h(int (*x)()) { } // ill-formed: redefinition of h(int())—end example ]
typedef const int cInt; int f (int); int f (const int); // redeclaration of f(int) int f (int) { /* ... */ } // definition of f(int) int f (cInt) { /* ... */ } // error: redefinition of f(int)—end example ] Only the const and volatile type-specifiers at the outermost level of the parameter type specification are ignored in this fashion; const and volatile type-specifiers buried within a parameter type specification are significant and can be used to distinguish overloaded function declarations. 123 In particular, for any type T , “pointer to T ”, “pointer to const T ”, and “pointer to volatile T ” are considered distinct parameter types, as are “reference to T ”, “reference to const T ”, and “reference to volatile T”.
void f (int i, int j); void f (int i, int j = 99); // OK: redeclaration of f(int, int) void f (int i = 88, int j); // OK: redeclaration of f(int, int) void f (); // OK: overloaded declaration of f void prog () { f (1, 2); // OK: call f(int, int) f (1); // OK: call f(int, int) f (); // Error: f(int, int) or f()? }—end example ]
—end note ]
footnote 123 When a parameter type includes a function type, such as in the case of a parameter type that is a pointer to function, the const and volatile type-specifiers at the outermost level of the parameter type specifications for the inner function type are also ignored.
1 同名の関数宣言は、同じスコープにあり等価な仮引数宣言を持つ時、同一の関数を指す (16.1)。 派生クラスのメンバ関数は、基底クラスの同名のメンバ関数とは別のスコープにある。[例:
struct B { int f(int); }; struct D : B { int f(const char*); };
この時 D::f(const char*)
は B::f(int)
に多重定義を加えるのではなく、これを隠蔽する。
void h(D* pd) { pd->f(1); // error: // D::f(const char*) は B::f(int) を隠蔽する pd->B::f(1); // OK pd->f("Ben"); // OK, D::f が呼び出される }
- 例終わり ]
異なる型の変換関数は「名前」が違うという解釈なのだと思われる。
等価な仮引数宣言を持つが戻り値が異なる関数宣言は、関数型として異なるので多重定義になる (16/1)。 しかし等価な仮引数宣言を持ち戻り値が異なる関数宣言は、多重定義できない (16.1/(2.1)。 これにより等価な仮引数宣言を持つだけで、それが同一の関数であることが保証される。
原文には function member という語が出てくるがこれは member function の表記揺れであろう。
テンプレート引数について言及がないのは、この段落の関数宣言とは関数テンプレートは含まないからということだろうか。 しかし、そうだとすると関数テンプレートの場合に同一の宣言かどうかを判定する記述が与えられず片手落ちである。
2 局所的に宣言された関数は、外側のスコープにある関数とは異なるスコープになる。[例:
void f(const char*); void g() { extern void f(int); f("asdf"); // error: f(int) は f(const char*) を隠蔽する。 // 従って、このスコープに f(const char*) は存在しない。 } void caller () { extern void callee(int, int); { extern void callee(int); // callee(int, int) を隠蔽する。 callee(88, 99); // error: このスコープには callee(int) しかない。 } }
- 例終わり ]
3 多重定義されたメンバ関数のそれぞれに対して異なるアクセス規則を割り当てることができる。[例:
class buffer { private: char* p; int size; protected: buffer(int s, char* store) { size = s; p = store; } public: buffer(int s) { p = new char[size = s]; } };
- 例終わり ]
1 Two function declarations of the same name refer to the same function if they are in the same scope and have equivalent parameter declarations (16.1). A function member of a derived class is not in the same scope as a function member of the same name in a base class. [Example:
struct B { int f(int); }; struct D : B { int f(const char*); };
Here D::f(const char*) hides B::f(int) rather than overloading it.
void h(D* pd) { pd->f(1); // error: // D::f(const char*) hides B::f(int) pd->B::f(1); // OK pd->f("Ben"); // OK, calls D::f }
—end example ]
2 A locally declared function is not in the same scope as a function in a containing scope. [Example:
void f(const char*); void g() { extern void f(int); f("asdf"); // error: f(int) hides f(const char*) // so there is no f(const char*) in this scope } void caller () { extern void callee(int, int); { extern void callee(int); // hides callee(int, int) callee(88, 99); // error: only callee(int) in scope } }
—end example ]
3 Different versions of an overloaded member function can be given different access rules. [Example:
class buffer { private: char* p; int size; protected: buffer(int s, char* store) { size = s; p = store; } public: buffer(int s) { p = new char[size = s]; } };
—end example ]
1 多重定義解決は、関数の呼び出しにおいて最適の関数を選択する仕組みである。 実引数の式のリストと、呼び出しの文脈における候補関数 (candidate functions) の集合が考慮される。 選択の判断材料として、実引数の数、 実引数の仮引数型のリストへの合致度合い、 オブジェクトの暗黙オブジェクト仮引数への合致度合い、 その他の色々の候補関数の性質が用いられる。 [註: 多重定義解決で選択される関数は必ずしもその文脈で適切であるとは限らない。 関数のアクセス可能性などの他の制限によって、その呼び出しが不適格になることがある。 - 註終わり ]
2 7つの異なる文脈で多重定義解決が実行される:
それぞれの文脈ごとに候補関数の集合と実引数のリストの決定方法が与えられる。 ひとたび候補関数と実引数のリストが与えられれば、最適な関数の選択方法は何れの文脈でも共通である:
3 最適な呼び出し可能関数が一意に存在するときに多重定義解決は成功とし、その関数が結果となる。 それ以外の場合は、多重定義解決は失敗であり、その関数呼び出しは不適格である。 多重定義解決が成功したものの最適な呼び出し可能関数がその文脈でアクセス可能 (Clause 14) でないとき、プログラムは不適格である。
原文 16.3/(2.8) the proper number of arguments は the proper number of parameters の誤りではないか。
1 Overload resolution is a mechanism for selecting the best function to call given a list of expressions that are to be the arguments of the call and a set of candidate functions that can be called based on the context of the call. The selection criteria for the best function are the number of arguments, how well the arguments match the parameter-type-list of the candidate function, how well (for non-static member functions) the object matches the implicit object parameter, and certain other properties of the candidate function. [Note: The function selected by overload resolution is not guaranteed to be appropriate for the context. Other restrictions, such as the accessibility of the function, can make its use in the calling context ill-formed. —end note ]
2 Overload resolution selects the function to call in seven distinct contexts within the language:
Each of these contexts defines the set of candidate functions and the list of arguments in its own unique way. But, once the candidate functions and argument lists have been identified, the selection of the best function is the same in all cases:
3 If a best viable function exists and is unique, overload resolution succeeds and produces it as the result. Otherwise overload resolution fails and the invocation is ill-formed. When overload resolution succeeds, and the best viable function is not accessible (Clause 14) in the context in which it is used, the program is ill-formed.
1 この節 16.3.1 では多重定義の行われる7つの文脈のそれぞれについて、 多重定義解決に使われる候補関数の集合と実引数リストを記述する。 ここで定義されるソースコードの変換や構造は多重定義解決を定義するために導入するもので、 処理系は必ずしもこれらの変換や構造を実際に使用しなくても良い。
2 候補関数の集合は、同じ実引数リストに対してメンバ関数と非メンバ関数の両方を含むこともある。 この異質の候補関数を含む集合について実引数と仮引数のリストを比較するために、 メンバ関数は暗黙オブジェクト仮引数 (implicit object parameter) という追加の仮引数を持つものとみなし、 この仮引数はメンバ関数を呼び出す対象のオブジェクトを表す。 多重定義解決において、静的・非静的メンバ関数は共に暗黙オブジェクト仮引数を持つとする。 一方でコンストラクタは暗黙オブジェクト仮引数を持たない。
非メンバ関数には暗黙オブジェクト仮引数を導入しない。何故ならば、
3 同様に、文脈に応じて、暗黙オブジェクト実引数 (implied object argument) を含む実引数リストが構築される。 暗黙オブジェクト実引数はメンバ関数を呼び出す対象のオブジェクトを表す。 実引数と仮引数はそれぞれの属するリスト中の位置で指定されるので、 ここでは暗黙オブジェクト仮引数・実引数があるときは、 それはリスト中の一番初めの実引数・仮引数であるとして取り扱うことにする。
4 非静的メンバ関数の暗黙オブジェクト仮引数の型は、
&
ref 修飾子のついた関数については
cv X
の左辺値参照であり、&&
ref 修飾子のついた関数については
cv X
の右辺値参照である。但し、X
は関数がメンバとして属するクラスであり、
cv はそのメンバ関数の宣言の cv 修飾である。[例:
クラス X
の const
メンバ関数について、
追加の仮引数は const X
の参照を持つと考える。- 例終わり ]
変換関数は、
暗黙オブジェクト仮引数の型を決めるために、
暗黙オブジェクト実引数のクラスのメンバであると考える。
using 宣言を用いて派生クラスに導入された変換関数以外の関数は、
暗黙オブジェクト仮引数の型を決めるために、
派生クラスのメンバであると考える。
静的メンバ関数については、
(もし採用された場合、暗黙オブジェクト実引数は使われないので)、
暗黙オブジェクト仮引数はいかなるオブジェクトにも一致すると考える。
[註: 静的メンバ関数の暗黙オブジェクト仮引数には実際の型は決めず、
また、その仮引数に対する変換列が決定されることもない (16.3.3) - 註終わり ]
5 多重定義解決において、暗黙オブジェクト実引数は他の実引数と同様に取り扱う。 一方で暗黙オブジェクト仮引数については、 実引数の型を一致させるためにユーザ定義変換を使えない規則 16.3.3.1/7 のために、 自身が暗黙オブジェクト仮引数であることを覚えておく必要がある。 ref 修飾子のない非静的メンバ関数については以下の追加の規則が適用される:
6 リスト初期化以外ではユーザ定義変換は高々1回までなので、 最適なユーザ定義変換を選ぶときに特別な規則が適用される(16.3.3, 16.3.3.1)。[例:
class T { public: T(); }; class C : T { public: C(int); }; T a = 1; // 不適格: T(C(1)) は考慮されない
- 例終わり ]
7 候補が関数テンプレートの場合、 テンプレート実引数推論 (17.8.3, 17.8.2) を経て、 候補の関数テンプレート特殊化が生成され、 以降は通常の候補関数と同様に取り扱われる124。 与えられた関数名は、1つ以上の関数テンプレートと 多重定義された非テンプレート関数の集合を同時に指すこともある。 その場合は、それぞれの関数テンプレートから生成された候補関数は、 非テンプレート候補関数の集合に合流させて取り扱われる。
8 どの文脈でも、既定化されたムーブコンストラクタ (15.8) と削除された代入演算子は候補関数の集合に含まれない。
footnote 124 実引数推論の過程で関数テンプレート特殊化の仮引数の型は完全に定まる。 つまり、関数テンプレート特殊化の仮引数にはテンプレート仮引数は残らない。 従って、特に指定がない限りは、関数テンプレート特殊化と非テンプレート関数 (11.3.5) は、 多重定義解決の残りの部分で同等に取り扱われる。
1 The subclauses of 16.3.1 describe the set of candidate functions and the argument list submitted to overload resolution in each of the seven contexts in which overload resolution is used. The source transformations and constructions defined in these subclauses are only for the purpose of describing the overload resolution process. An implementation is not required to use such transformations and constructions.
2 The set of candidate functions can contain both member and non-member functions to be resolved against the same argument list. So that argument and parameter lists are comparable within this heterogeneous set, a member function is considered to have an extra parameter, called the implicit object parameter, which represents the object for which the member function has been called. For the purposes of overload resolution, both static and non-static member functions have an implicit object parameter, but constructors do not.
3 Similarly, when appropriate, the context can construct an argument list that contains an implied object argument to denote the object to be operated on. Since arguments and parameters are associated by position within their respective lists, the convention is that the implicit object parameter, if present, is always the first parameter and the implied object argument, if present, is always the first argument.
4 For non-static member functions, the type of the implicit object parameter is
where X is the class of which the function is a member and cv is the cv-qualification on the member function declaration. [Example: For a const member function of class X , the extra parameter is assumed to have type “reference to const X ”. —end example ] For conversion functions, the function is considered to be a member of the class of the implied object argument for the purpose of defining the type of the implicit object parameter. For non-conversion functions introduced by a using-declaration into a derived class, the function is considered to be a member of the derived class for the purpose of defining the type of the implicit object parameter. For static member functions, the implicit object parameter is considered to match any object (since if the function is selected, the object is discarded). [Note: No actual type is established for the implicit object parameter of a static member function, and no attempt will be made to determine a conversion sequence for that parameter (16.3.3). —end note ]
5 During overload resolution, the implied object argument is indistinguishable from other arguments. The implicit object parameter, however, retains its identity since no user-defined conversions can be applied to achieve a type match with it. For non-static member functions declared without a ref-qualifier, an additional rule applies:
6 Because other than in list-initialization only one user-defined conversion is allowed in an implicit conversion sequence, special rules apply when selecting the best user-defined conversion (16.3.3, 16.3.3.1). [Example:
class T { public: T(); }; class C : T { public: C(int); }; T a = 1; // ill-formed: T(C(1)) not tried
—end example ]
7 In each case where a candidate is a function template, candidate function template specializations are generated using template argument deduction (17.8.3, 17.8.2). Those candidates are then handled as candidate functions in the usual way. 124 A given name can refer to one or more function templates and also to a set of overloaded non-template functions. In such a case, the candidate functions generated from each function template are combined with the set of non-template candidate functions.
8 A defaulted move constructor or assignment operator (15.8) that is defined as deleted is excluded from the set of candidate functions in all contexts.
footnote 124 The process of argument deduction fully determines the parameter types of the function template specializations, i.e., the parameters of function template specializations contain no template parameter types. Therefore, except where specified otherwise, function template specializations and non-template functions (11.3.5) are treated equivalently for the remainder of overload resolution.
1 関数呼び出し (8.2.2)
(
expression-listopt )
において、postfix-expression が多重定義された関数・関数テンプレートの集合を表すとき、 多重定義解決は 16.3.1.1.1 で指定される方法で適用される。 postfix-expression がクラス型のオブジェクトを表すとき、 多重定義解決は 16.3.1.1.2 で指定される方法で適用される。
2 postfix-expression が多重定義された関数・関数テンプレートの集合のアドレスを表すとき、 その集合に対して上記の多重定義解決を適用する。 多重定義解決で選ばれた関数が非静的メンバ関数のとき、プログラムは不適格である。 [註: 他の文脈における多重定義された集合のアドレスの解決は 16.4 で述べる。 - 註終わり ]
1 In a function call (8.2.2)
(
expression-listopt )
if the postfix-expression denotes a set of overloaded functions and/or function templates, overload resolution is applied as specified in 16.3.1.1.1. If the postfix-expression denotes an object of class type, overload resolution is applied as specified in 16.3.1.1.2.
2 If the postfix-expression denotes the address of a set of overloaded functions and/or function templates, overload resolution is applied using that set as described above. If the function selected by overload resolution is a non-static member function, the program is ill-formed. [Note: The resolution of the address of an overload set in other contexts is described in 16.4. —end note ]
1 16.3.1.1.1 で取り扱う関数呼び出しは、 postfix-expression が呼び出す関数候補の名前を含むものである。 そのような postfix-expression は、 以下の形式、またはそれを任意の深さの丸括弧で括ったものになっている:
.
id-expression
->
id-expression
これに基づき2つの文法的分類、即ち修飾付き関数呼び出し (qualified function calls) と修飾なし関数呼び出し (unqualified function calls) が定められる。
2
修飾付き関数呼び出しでは、
->
または .
演算子に続く
id-expression が解決する名前になる。
構文 A->B
は一般に (*A).B
に等価なため、
以降 Clause 16 では、一般性を失うことなく、
全てのメンバ関数呼び出しはオブジェクトと .
演算子を用いた形式に正規化されているものとして扱う。
加えて、Clause 16 では .
演算子の左辺 postfix-expression の型は
クラス型 T
を以て "cv T
" とする125。
この仮定の下、関数呼び出しの id-expression は、
T
のメンバ関数として
クラス中の名前探索 (13.2) の規則に基いて探索される。
この探索で見つかった関数宣言が候補関数の集合を為す。
実引数リストは、
正規化した呼び出しにおける .
演算子の左辺を暗黙オブジェクト実引数として、
関数呼び出しの expression-list を拡張したものになる (16.3.1)。
3
修飾なしの関数呼び出しでは名前は ->
または .
演算子によって修飾されず、
より一般の形 primary-expression をしている。
関数呼び出しの文脈では、関数呼び出しの通常の名前探索の規則 (6.4) によって名前が探索される。
名前探索で見つかった関数宣言が候補関数となる。
名前探索の規則により、候補関数の集合は (1) 全て非メンバ関数であるか
(2) 全て或るクラス T
のメンバ関数である。
(1) の場合、実引数リストは関数呼び出しの expression-list と同じである。
(2) の場合、修飾付き関数呼び出しのときと同様に、
実引数リストは暗黙オブジェクト実引数によって
関数呼び出しの expression-list を拡張したものになる。
キーワード this
(12.2.2.1) がスコープ内にあって
クラス T
またはその派生クラスを指すとき、
暗黙オブジェクト実引数は (*this)
である。
キーワード this
がスコープ内にないか他のクラスを指すとき、
型 T
の仮想的に導入されたオブジェクトが暗黙オブジェクト実引数になる126。
実引数リストが仮想的に導入されたオブジェクトで拡張された場合、
多重定義解決の結果が T
の非静的メンバ関数ならば、その呼び出しは不適格である。
原文に contrived object という単語が出てくるが、これは規格の中でこの箇所でしか出てこない。
footnote 125 オブジェクトが glvalue であってもクラス型の prvalue であっても、 オブジェクトの型の cv 修飾子は多重定義解決で意味を持つことに注意する。
footnote 126 多重定義解決の手続き上、 メンバ関数の暗黙オブジェクト仮引数に対応して 暗黙オブジェクト実引数を仮想的に導入する必要がある。 このとき静的関数しか許されないので この暗黙オブジェクト実引数は最終的な関数呼び出しには用いられない。 メンバ関数は全て同じ暗黙オブジェクト仮引数を持つので、 この仮想的に導入されるオブジェクトは各関数の選択・棄却には影響を与えない。
「メンバ関数は全て同じ暗黙オブジェクト仮引数を持つので (原文: Since the member functions all have the same implicit object parameter)」→ 16.3.1/4 に従い、 関数の ref-qualifier, cv-qualifier によって仮引数は異なるのではないか。 これは「静的メンバ関数は~」の誤りである気がする。
1 Of interest in 16.3.1.1.1 are only those function calls in which the postfix-expression ultimately contains a name that denotes one or more functions that might be called. Such a postfix-expression, perhaps nested arbitrarily deep in parentheses, has one of the following forms:
.
id-expression
->
id-expression
These represent two syntactic subcategories of function calls: qualified function calls and unqualified function calls.
2 In qualified function calls, the name to be resolved is an id-expression and is preceded by an -> or . operator. Since the construct A->B is generally equivalent to (*A).B , the rest of Clause 16 assumes, without loss of generality, that all member function calls have been normalized to the form that uses an object and the . operator. Furthermore, Clause 16 assumes that the postfix-expression that is the left operand of the . operator has type “cv T ” where T denotes a class 125 . Under this assumption, the id-expression in the call is looked up as a member function of T following the rules for looking up names in classes (13.2). The function declarations found by that lookup constitute the set of candidate functions. The argument list is the expression-list in the call augmented by the addition of the left operand of the . operator in the normalized member function call as the implied object argument (16.3.1).
3 In unqualified function calls, the name is not qualified by an -> or . operator and has the more general form of a primary-expression. The name is looked up in the context of the function call following the normal rules for name lookup in function calls (6.4). The function declarations found by that lookup constitute the set of candidate functions. Because of the rules for name lookup, the set of candidate functions consists (1) entirely of non-member functions or (2) entirely of member functions of some class T . In case (1), the argument list is the same as the expression-list in the call. In case (2), the argument list is the expression-list in the call augmented by the addition of an implied object argument as in a qualified function call. If the keyword this (12.2.2.1) is in scope and refers to class T , or a derived class of T , then the implied object argument is (*this) . If the keyword this is not in scope or refers to another class, then a contrived object of type T becomes the implied object argument 126 . If the argument list is augmented by a contrived object and overload resolution selects one of the non-static member functions of T, the call is ill-formed.
footnote 125 Note that cv-qualifiers on the type of objects are significant in overload resolution for both glvalue and class prvalue objects.
footnote 126 An implied object argument must be contrived to correspond to the implicit object parameter attributed to member functions during overload resolution. It is not used in the call to the selected function. Since the member functions all have the same implicit object parameter, the contrived object will not be the cause to select or reject a function.
1
関数呼び出し構文の primary-expression E
が
型 "cv T
" のクラスオブジェクトに評価されるとき、
候補関数の集合は少なくとも T
の関数呼び出し演算子を含む。
T
の関数呼び出し演算子は、
(E).operator()
における名前 operator()
の通常の探索によって得られる。
2
更に、以下の形式を持つ T
の非明示的な変換関数について考える。
operator
conversion-type-id ()
cv-qualifier
ref-qualifieropt
noexcept-specifieropt
attribute-specifier-seqopt ;
cv-qualifier が cv と同じかより強い cv 修飾であり、
conversion-type-id が
型 "(P
1 , ..., P
n) を受け取り R
を返す関数ポインタ"、
または型 "(P
1 , ..., P
n) を受け取り R
を返す関数ポインタの参照"
または型 "(P
1 , ..., P
n) を受け取り R
を返す関数の参照" ならば、
以下の形式の代理呼び出し関数 (surrogate call function) も候補関数に加えられる。
R
call-function
(
conversion-type-id F,
P1
a1 ,
...,
P
n a
n)
{ return F (a1 ,
..., a
n); }
但し call-function は他と区別できる一意な名前とする。
T
の基底クラスで宣言された非明示的な変換関数のそれぞれについても、
その変換関数が T
において他の intervening 宣言によって隠蔽されない限りにおいて、
同様にして代理呼び出し関数が候補関数の集合に追加される127。
代理呼び出し関数は完全転送でなくて良いのか? やはり駄目な気がする
3
多重定義解決によってこの様な代理呼び出し関数が選ばれたとき、
対応する変換関数を呼び出して E
を適切な関数ポインタまたは参照に変換し、
それからその関数が関数呼び出し構文の実引数によって呼び出される。
もし (曖昧であるなどの理由で) 変換関数が呼び出せないとき、プログラムは不適格である。
ところで「呼び出しは不適格である」と「プログラムは不適格である」に区別はあるのだろうか。
4
多重定義解決に渡される実引数リストは、
暗黙オブジェクト実引数 (E)
とそれに続く関数呼び出し構文に与えられた実引数の式からなる。
[註: 呼び出しを関数呼出し演算子と比較するとき、
暗黙オブジェクト実引数は関数呼び出し演算子の暗黙オブジェクト仮引数と比較される。
呼び出しを代理呼び出し関数と比較するとき、
暗黙オブジェクト実引数は代理呼び出し関数の第1仮引数と比較される。
代理呼び出し関数の元になった変換関数は、
暗黙オブジェクト実引数を第1仮引数が要求する関数ポインタまたは参照に変換するために、
第1仮引数の変換列の中で使われる。- 註終わり ] [例:
int f1(int); int f2(float); typedef int (*fp1)(int); typedef int (*fp2)(float); struct A { operator fp1() { return f1; } operator fp2() { return f2; } } a; int i = a(1); // 変換関数から返されるポインタを通して f1 が呼び出される
—end example ]
footnote 127 この手順により、同一の宣言であるまたは戻り値の型だけが異なるために、 互いに多重定義解決において区別できない複数の候補関数が生成されることがある。 多重定義解決において、このような区別できない候補関数よりも良い他の候補が見つからない場合は、呼び出しは曖昧になる。
1 If the primary-expression E in the function call syntax evaluates to a class object of type “cv T ”, then the set of candidate functions includes at least the function call operators of T . The function call operators of T are obtained by ordinary lookup of the name operator() in the context of (E).operator().
2 In addition, for each non-explicit conversion function declared in T of the form
operator
conversion-type-id ()
cv-qualifier
ref-qualifieropt
noexcept-specifieropt
attribute-specifier-seqopt ;
where cv-qualifier is the same cv-qualification as, or a greater cv-qualification than, cv, and where conversion- type-id denotes the type “pointer to function of ( P 1 ,...,P n ) returning R ”, or the type “reference to pointer to function of ( P 1 ,...,P n ) returning R ”, or the type “reference to function of ( P 1 ,...,P n ) returning R ”, a surrogate call function with the unique name call-function and having the form
R
call-function
(
conversion-type-id F,
P1
a1 ,
...,
P
n a
n)
{ return F (a1 ,
..., a
n); }
is also considered as a candidate function. Similarly, surrogate call functions are added to the set of candidate functions for each non-explicit conversion function declared in a base class of T provided the function is not hidden within T by another intervening declaration 127 .
3 If such a surrogate call function is selected by overload resolution, the corresponding conversion function will be called to convert E to the appropriate function pointer or reference, and the function will then be invoked with the arguments of the call. If the conversion function cannot be called (e.g., because of an ambiguity), the program is ill-formed.
4 The argument list submitted to overload resolution consists of the argument expressions present in the function call syntax preceded by the implied object argument (E) . [Note: When comparing the call against the function call operators, the implied object argument is compared against the implicit object parameter of the function call operator. When comparing the call against a surrogate call function, the implied object argument is compared against the first parameter of the surrogate call function. The conversion function from which the surrogate call function was derived will be used in the conversion sequence for that parameter since it converts the implied object argument to the appropriate function pointer or reference required by that first parameter. —end note ] [Example:
int f1(int); int f2(float); typedef int (*fp1)(int); typedef int (*fp2)(float); struct A { operator fp1() { return f1; } operator fp2() { return f2; } } a; int i = a(1); // calls f1 via pointer returned from conversion function
—end example ]
footnote 127 Note that this construction can yield candidate call functions that cannot be differentiated one from the other by overload resolution because they have identical declarations or differ only in their return type. The call will be ambiguous if overload resolution cannot select a match to the call that is uniquely better than such undifferentiable functions.
1
クラス型か列挙型の被演算子を持たない演算子は、組み込み演算子として Clause 8 に従って解釈される。
[註: 演算子 .
, .*
, ::
は、
多重定義できないので常に Clause8 に従って解釈される組み込み演算子である。
演算子 :?
も多重定義できないが、
第2・第3被演算子がクラス型または列挙型のときこれらに適用される変換は、
この節の規則によって決まる (8.16)。- 註終わり ] [例:
struct String { String (const String&); String (const char*); operator const char* (); }; String operator + (const String&, const String&); void f() { const char* p= "one" + "two"; // どちらの被演算子もクラス型または列挙型ではないので不適格。 int I = 1 + 1; // この操作を実行しうるクラス型・列挙型が存在したとしても、 // 常に結果は 2 になる。 }
- 例終わり ]
2
何れかの被演算子がクラス型または列挙型のとき、
演算子を実装するユーザ定義の演算子関数が宣言されているか、
そうでなければ被演算子を組み込み演算子に合う型に変換するユーザ定義の変換が必要になる。
このとき演算を実行する上でどの演算子関数・組み込み演算子が呼び出されるかが多重定義解決で決まる。
従って、演算子記法は初めに、表 12 に示したような等価な関数呼び出し記法に変形される
(但し @
は表中に示した各節で述べる演算子のうちの何れかである)。
ただし、被演算子は組み込み演算子 (Clause 8) について既に述べた順序で副作用完了する。
節 | 式 | メンバ関数として | 非メンバ関数として |
---|---|---|---|
16.5.1 | @a | (a).operator@ () | operator@(a) |
16.5.2 | a@b | (a).operator@ (b) | operator@(a, b) |
16.5.3 | a=b | (a).operator= (b) | |
16.5.5 | a[b] | (a).operator[](b) | |
16.5.6 | a-> | (a).operator->() | |
16.5.7 | a@ | (a).operator@ (0) | operator@(a, 0) |
3
単項演算子 @
の被演算子の
cv 修飾を除いた型を T1
とする。
二項演算子 @
の左被演算子・右被演算子の
cv 修飾を除いた型をそれぞれ T1
・T2
とする。
単項演算子と二項演算子について、3種類の候補関数
――指定されたメンバー候補 (designated member candidates)、非メンバ候補 (non-member candidates)、組み込み候補 (built-in candidates)――
が以下のようにして構築される。
T1
が完全クラス型または現在定義しているクラス型の場合、
メンバ候補の集合は T1::operator@
の修飾付き探索 (16.3.1.1.1) の結果とする。
それ以外の場合は、メンバ候補の集合は空とする。
operator@
の修飾なし探索を行った結果とする。
但し、クラス型を持つ被演算子がない場合は、探索結果の非メンバ関数のうち、
T1
が列挙型でかつ第1仮引数の型が
T1
または "cv T1
の参照" であるか、
もし右被演算子が存在すれば T2
が列挙型でかつ第2仮引数の型が
T2
または "cv T2
の参照" であるような物のみが候補関数である。
,
、単項演算子 &
、演算子 ->
については、
組み込み候補は空である。それ以外の全ての演算子について、
組み込み候補は 16.6 で定義される候補演算子関数のうち、
対象の演算子と比べて以下を満たすものを全て含む。
関数テンプレート特殊化非メンバ候補 vs 組み込み候補はどうなるのか? これは 16.6 をよく見る必要がある■
4 組み込みの代入演算子については、左被演算子の変換は以下のように制限される:
5 その他の演算子については、上記の制限はない。
6 多重定義解決に用いる候補関数の集合は、メンバー候補、非メンバー候補、組み込み候補の和集合である。 実引数リストは、その演算子の全ての被演算子を含む。 最適な候補関数が 16.3.2, 16.3.3 に基づき選択される128。[例:
struct A { operator int(); }; A operator+(const A&, const A&); void m() { A a, b; a + b; // int(a) + int(b) ではなく operator+(a, b) が選ばれる。 }
—end example ]
7 組み込み候補が多重定義解決により選ばれた場合、 先ずクラス型の被演算子は、選ばれた演算関数の対応する仮引数の型に変換される。 但し、ユーザ定義変換列 (16.3.3.1.2) の第2の標準変換列は適用されない。 その後に演算子は対応する組み込み演算子として Clause 8 に従って解釈される。[例:
struct X { operator double(); }; struct Y { operator int*(); }; int *a = Y() + 100.0; // error: pointer arithmetic requires integral operand int *b = Y() + X(); // error: pointer arithmetic requires integral operand
- 例終わり ]
先ず第2標準変換列を考慮に入れて多重定義解決が行われ、 その後で組み込み演算子が選ばれた場合には第2標準変換列を適用せずに Clause 8 の規則に転送される。 従って、組み込み演算子が Clause 8 によって不適格になり、 他に不適格にならない演算子が存在したとしても、 組み込み演算子が選ばれることがある。[例:
struct X { X(int*) {} }; struct Y { operator double() { return 0.0; } }; int operator+(X, int) { return 0; } // #1 // #2 は組み込み演算子 T* operator+(T*, std::ptrdiff_t); (int*) 0 + Y(); // 不適格: #2 が多重定義で選ばれ (int*) 0 + (double) Y() が考慮される。 // しかしこれは 8.7/1 により不適格になる。
- 例終わり ]
この点に関しては自信がなかったので複数のコンパイラで試したがそれぞれに違った結果を与えた。 Stack Overflow で質問 した所、自分の当初の解釈で正しく、各コンパイラが間違っているとのこと。
// Case1: これは N4569 16.3.1.2/7 の例をそのまま持ってきたのでエラーになるべき。 struct X { operator double() {return 0.0;} }; struct Y { operator int*() {return 0;} }; int main() { int* a = Y() + 100.0; // error int* b = Y() + X(); // error (void) a; (void) b; }
// Case2: これは規格を愚直に解釈すればエラーになるべき。 #include <iostream> void print_type(int) { std::cout << "int" << std::endl; } void print_type(int*) { std::cout << "int*" << std::endl; } struct X { X(int*) {} }; struct Y { operator double() { return 0.0; } }; int operator+(X, int) { return 0; } int main() { print_type((int*) 0 + Y()); // error }
Case1 | Case2 | バグ報告 | |
---|---|---|---|
C++98 | 適格 | int* | -- |
C++14 | 不適格 | 不適格 | -- |
gcc 8.0.0 | 不適格 | int |
81789 |
clang 6.0.0 | 適格 | int* |
34138 |
msc 19.10 | 不適格 | int |
92207 |
icc | 不適格 | int* |
未だ提出していない |
注意することとしてここの文面は CWG 1687 によって C++14 から変更された。 元々、第2標準変換列も含めて変換が行われてから組み込み演算の規則が適用されていた。 Stack Overflow のコメントから推測するに、第2標準変換列を必要とするような組み込み演算子を呼び出し不能にしなかったのは、 この変更により多重定義解決で選ばれる関数が変更されて既存のコードの動作が変化することを恐れた可能性がある (単に可能性だが)。
しかし調べると GCC は昔から (C++14 以前から) この動作だったようで、 CWG 1687 は GCC の動作を参考に提案された可能性もある。 だとすると、CWG 1687 で呼び出し可能性ではなく取ってつけたような文章をここに入れたことが間違いの可能性も未だ残っている。
試した結果そもそも gcc/clang にバグがある様だ。 第2標準変換列が恒等変換でなければならないという規則は C++03 にはなく C++14 で追加された様だ。 gcc では -std=c++?? に関係なく常に C++14 以降の動作である。 clang では -std=c++?? に関係なく常に C++11 以前の動作である。
// Example from N4140 13.3.1.2/7, N4569 16.3.1.2/7 // // gcc emits diagnostics as expected. // clang compiles without diagnostics. struct X { operator double() {return 0.0;} }; struct Y { operator int*() {return 0;} }; int main() { int* a = Y() + 100.0; int* b = Y() + X(); (void) a; (void) b; }
取り敢えず少なくとも gcc の方が N4659 に対応しているようなのでこれで試す。
struct A { int operator-(A const&) {return 2;} // #1 friend int operator*(A, A) {return 3;} // #2 }; int operator+(A, A) {return 1;} // #3 struct X { operator A() const {return A();} }; struct Y { operator A() const {return A();} }; void test1() { X x; Y y; (void) (x + y); // OK: #3 operator+ は非メンバ候補 (void) (x - y); // Error: #1 operator- はメンバ候補には挙がらない (void) (x * y); // Error: #2 operator* は ADL でないと見えない } struct B { B(int*) {} }; int operator+(B, int) {return 4;} // #4 struct N { operator double() const {return 0.0;} }; // #5 は組み込み演算子 operator+(int* int) とする。 void test2() { int* p = nullptr; N n; (void) (p + n); // 実引数: (int*, N), 非メンバ候補: #4 int (B, int), 組み込み候補: int* (int*, int) // → gcc では p + n は int になる。これはグレー。 // → clang では p + n は int* になる。どうやら p + (int) (double) n になっている。しかしこれは Clause 5 で禁止されるはずだ。 }
GCC は (b) の解釈のようだ。 しかし再度探しても、ユーザ定義変換列の中の第2標準変換列が組込候補に対して恒等変換でなければならなという記述は見つからない。 これの根拠は何処にあるのか?
もう少し単純化した例を考える。
#include <iostream> void print_type(int) { std::cout << "int" << std::endl; } void print_type(int*) { std::cout << "int*" << std::endl; } struct X { X(int*) {} }; struct Y { operator double() { return 0.0; } }; int operator+(X, int) { return 0; } int main() { int* p = 0; Y y; print_type(p + y); // expected : diagnostics // gcc : int // clang : int* }
そもそもこの規則が C++14 で追加された経緯も確認しておくべきだろう。
この規則が追加された時に慎重に考えられずに適当に追加された可能性が高い気がする。
→CWG 1687 で理由付きで変更されている。尤もだ。
うーん。これを見る限り、多重定義解決の過程では第2標準変換列として非自明なものを許すが、
最終的なチェックを Clause 5 で行うために取り敢えず第2標準変換列の手前まで変換を行うという事に見える。
ということは (a) ということのように思われる。
1687. Conversions of operands of built-in operators
Section: 13.3.1.2 [over.match.oper] Status: C++14 Submitter: Richard Smith Date: 2013-05-17
[Moved to DR at the February, 2014 meeting.]
Consider an example like:
struct Y { operator int*(); }; extern int *p; int *a = p + 100.0; // #1 int *b = Y() + 100.0; // #2
#1 is ill-formed because it violates the requirement of 5.7 [expr.add] that the non-pointer operand have integral or enumeration type. It appears that #2 is well-formed, however, because 13.3.1.2 [over.match.oper] paragraph 7 says,
If a built-in candidate is selected by overload resolution, the operands are converted to the types of the corresponding parameters of the selected operation function. Then the operator is treated as the corresponding built-in operator and interpreted according to Clause 5 [expr].
In this case, the selected operation function is
int *operator+(int *, std::ptrdiff_t)
100.0 is thus converted to std::ptrdiff_t before reaching 5.7 [expr.add].
This problem could be addressed by restricting the conversion to the class or enumeration operand rather than both operands.
またもし (b) の様にしようとすると viable かどうかを判定する時に Clause 5 を引っ張り出して来なければならず複雑になる。
8
演算子 ->
の第2被演算子は、多重定義解決の際に無視され、
関数 operator->
が呼ばれるときの実引数にはならない。
関数 operator->
の戻り値に対して、
再度演算子 ->
が元々の第2非演算子と共に適用される129。
9
演算子 ,
、単項演算子 &
、演算子 ->
について、
呼び出し可能関数がない場合には演算子は組み込み演算子と見なされ Clause 8 によって解釈される。
10 [註: 以下の例に示したように、式中の演算子の名前探索の規則は、関数呼び出しにおける演算子関数の名前探索と異なる:
struct A { }; void operator + (A, A); struct B { void operator + (B); void f (); }; A a; void B::f() { operator+ (a,a); // error: グローバルの演算子はメンバによって隠蔽される。 a + a; // OK: グローバルの operator+ が呼び出される。 }
- 註終わり ]
footnote 128 候補関数の集合が空のとき、多重定義解決は失敗である。
16.3.1.2/9 については候補関数が空であったとしても、 Clause 8 へ行くので失敗ではないのではないか。■
footnote 129
関数 operator->
の戻り値がクラス型のとき、
更にもう一つの operator->
を選択して呼び出すことになる。
この処理は operator->
が非クラス型の値を返すまで続く。
無限ループになった場合に処理系はどうすれば良いか規定されていない。 つまり、correct execution が要求されるのでは?■
1 If no operand of an operator in an expression has a type that is a class or an enumeration, the operator is assumed to be a built-in operator and interpreted according to Clause 8. [Note: Because . , .* , and :: cannot be overloaded, these operators are always built-in operators interpreted according to Clause 8. ?: cannot be overloaded, but the rules in this subclause are used to determine the conversions to be applied to the second and third operands when they have class or enumeration type (8.16). —end note ] [Example:
struct String { String (const String&); String (const char*); operator const char* (); }; String operator + (const String&, const String&); void f() { const char* p= "one" + "two"; // ill-formed because neither operand has class or enumeration type int I = 1 + 1; // always evaluates to 2 even if class or enumeration types exist // that would perform the operation. }
—end example ]
2 If either operand has a type that is a class or an enumeration, a user-defined operator function might be declared that implements this operator or a user-defined conversion can be necessary to convert the operand to a type that is appropriate for a built-in operator. In this case, overload resolution is used to determine which operator function or built-in operator is to be invoked to implement the operator. Therefore, the operator notation is first transformed to the equivalent function-call notation as summarized in Table 12 (where @ denotes one of the operators covered in the specified subclause). However, the operands are sequenced in the order prescribed for the built-in operator (Clause 8).
Subclause | Expression | As member function | As non-member function |
---|---|---|---|
16.5.1 | @a | (a).operator@ () | operator@(a) |
16.5.2 | a@b | (a).operator@ (b) | operator@(a, b) |
16.5.3 | a=b | (a).operator= (b) | |
16.5.5 | a[b] | (a).operator[](b) | |
16.5.6 | a-> | (a).operator->() | |
16.5.7 | a@ | (a).operator@ (0) | operator@(a, 0) |
3 For a unary operator @ with an operand of a type whose cv-unqualified version is T1 , and for a binary operator @ with a left operand of a type whose cv-unqualified version is T1 and a right operand of a type whose cv-unqualified version is T2 , three sets of candidate functions, designated member candidates, non-member candidates and built-in candidates, are constructed as follows:
4 For the built-in assignment operators, conversions of the left operand are restricted as follows:
5 For all other operators, no such restrictions apply.
6 The set of candidate functions for overload resolution is the union of the member candidates, the non-member candidates, and the built-in candidates. The argument list contains all of the operands of the operator. The best function from the set of candidate functions is selected according to 16.3.2 and 16.3.3. 128 [Example:
struct A { operator int(); }; A operator+(const A&, const A&); void m() { A a, b; a + b; // operator+(a, b) chosen over int(a) + int(b) }
—end example ]
7 If a built-in candidate is selected by overload resolution, the operands of class type are converted to the types of the corresponding parameters of the selected operation function, except that the second standard conversion sequence of a user-defined conversion sequence (16.3.3.1.2) is not applied. Then the operator is treated as the corresponding built-in operator and interpreted according to Clause 8. [Example:
struct X { operator double(); }; struct Y { operator int*(); }; int *a = Y() + 100.0; // error: pointer arithmetic requires integral operand int *b = Y() + X(); // error: pointer arithmetic requires integral operand
—end example ]
8 The second operand of operator -> is ignored in selecting an operator-> function, and is not an argument when the operator-> function is called. When operator-> returns, the operator -> is applied to the value returned, with the original second operand. 129
9 If the operator is the operator , , the unary operator & , or the operator -> , and there are no viable functions, then the operator is assumed to be the built-in operator and interpreted according to Clause 8.
10 [Note: The lookup rules for operators in expressions are different than the lookup rules for operator function names in a function call, as shown in the following example:
struct A { }; void operator + (A, A); struct B { void operator + (B); void f (); }; A a; void B::f() { operator+ (a,a); // error: global operator hidden by member a + a; // OK: calls global operator+ }
—end note ]
footnote 128 If the set of candidate functions is empty, overload resolution is unsuccessful.
footnote 129 If the value returned by the operator-> function has class type, this may result in selecting and calling another operator-> function. The process repeats until an operator-> function returns a value of non-class type.
1 クラス型のオブジェクトを、 直接初期化 (11.6) または同じ型または派生クラス型からコピー初期化 (11.6) または既定初期化 (11.6) するとき、 多重定義解決でそのコンストラクを選ぶ。 コピー初期化の文脈にない直接初期化・既定初期化について、 候補関数は初期化されるオブジェクトのクラスの全てのコンストラクタである。 コピー初期化について、 候補関数はそのクラスの全ての変換コンストラクタ (15.3.1) である。 実引数リストは initializer 中の、 expression-list または assignment-expression である。
1 When objects of class type are direct-initialized (11.6), copy-initialized from an expression of the same or a derived class type (11.6), or default-initialized (11.6), overload resolution selects the constructor. For direct-initialization or default-initialization that is not in the context of copy-initialization, the candidate functions are all the constructors of the class of the object being initialized. For copy-initialization, the candidate functions are all the converting constructors (15.3.1) of that class. The argument list is the expression-list or assignment-expression of the initializer.
1 現在の文脈に対して候補関数の集合を求めた後 (16.3.1)、その中から呼び出し可能関数の集合が選ばれる。 後で、実引数の変換列 (16.3) を比べることによって、この集合の中からできるだけ実引数が合致する最適な関数が選択される。 呼び出し可能関数の選択では、(変換列の優先度を除く) 実引数と関数の仮引数の関係が考慮される。
2 先ず、候補関数が呼び出し可能関数であるためには、 実引数の数に対して仮引数が十分な数ある必要がある。
3
次に、F
が呼び出し可能関数であるためには、
それぞれの実引数を対応する F
の仮引数に変換する暗黙変換列 (16.3.3.1) が存在する必要がある。
仮引数が参照型の場合は、暗黙変換列には参照の束縛も含まれる。
従って、非 const 左辺値参照が rvalue に束縛できないこと、
また右辺値参照が lvalue に束縛できないことは、
関数の呼び出し可能性に影響を与える (16.3.3.1.4)。
foonote 130 この時、11.3.6 により m+1 個目以降の仮引数も既定の実引数を持っている。
原文 viable functions はここでは呼び出し可能関数と訳すことにした。 JIS C++ では二次候補関数と訳していることに注意する。
1 From the set of candidate functions constructed for a given context (16.3.1), a set of viable functions is chosen, from which the best function will be selected by comparing argument conversion sequences for the best fit (16.3.3). The selection of viable functions considers relationships between arguments and function parameters other than the ranking of conversion sequences.
2 First, to be a viable function, a candidate function shall have enough parameters to agree in number with the arguments in the list.
3 Second, for F to be a viable function, there shall exist for each argument an implicit conversion se- quence (16.3.3.1) that converts that argument to the corresponding parameter of F . If the parameter has reference type, the implicit conversion sequence includes the operation of binding the reference, and the fact that an lvalue reference to non- const cannot be bound to an rvalue and that an rvalue reference cannot be bound to an lvalue can affect the viability of the function (see 16.3.3.1.4).
foonote 130 According to 11.3.6, parameters following the (m+1)-st parameter must also have default arguments.
1
呼び出し可能関数 F
に対して
ICSi(F
) を次のように定義する:
F
が静的メンバ関数の場合は、任意の関数 G
について、
ICS1(F
) は
ICS1(G
) に比べて良くも悪くもなく、
また ICS1(G
) は
ICS1(F
) に比べて良くも悪くもない131。
それ以外の場合は、F
) は、
i 番目の実引数から F
の i 番目の仮引数型への暗黙変換列を表す。
16.3.3.1 で暗黙変換列を定義し、16.3.3.2 で或る暗黙変換列が他の暗黙変換列と比べて良いか悪いかを定義する。
その上で、次が満たされるときに、
呼び出し可能関数 F1
が
F2
よりも良いと定義する。
即ち、全ての実引数 i について
ICSi(F1
) が
ICSi(F2
) より悪くなく、
かつ
F1
) が
ICSj(F2
) より良いか、
そうでなければF1
の戻り値の型から目的の型 (初期化されるオブジェクトの型) への標準変換列が、
F2
の戻り値の型から目的の型への標準変換列より良い [例:
struct A { A(); operator int(); operator double(); } a; int i = a; // 変換の必要のない a.operator int() の方が、 // 後で int に変換する必要のある a.operator double() よりも良い。 float x = a; // 曖昧: どちらの選択肢も変換を必要とし、 // 何れかが他方より良いということはない。- 例終わり ] か、そうでなければ
F1
が初期化される参照と同じ種類の参照 (つまり右辺値参照または左辺値参照) であり、
F2
がそうでない [例:
template <class T> struct A { operator T&(); // #1 operator T&&(); // #2 }; typedef int Fn(); A<Fn> a; Fn& lf = a; // #1 が呼び出される Fn&& rf = a; // #2 が呼び出される- 例終わり ] か、そうでなければ
F1
が関数テンプレートの特殊化ではなく、
F2
が関数テンプレートの特殊化であるか、
そうでなければF1
と F2
が関数テンプレートの特殊化であり、
17.5.6.2 の半順序規則に基いて
F1
の関数テンプレートが
F2
の関数テンプレートに比べてより特殊であるか、
そうでなければ
F1
が deduction-guide (16.3.1.8) によって生成され、
F2
がそうでないか、
そうでなければF1
が copy deduction candidate (16.3.1.8) で
F2
がそうでないか、
そうでなければF1
が非テンプレートコンストラクタで
F2
がコンストラクタテンプレートによって生成される。[例:
template <class T> struct A { using value_type = T; A(value_type); // #1 A(const A&); // #2 A(T, T, int); // #3 template<class U> A(int, T, U); // #4 // #5 を copy deduction candidate A(A) とする。 }; A x(1, 2, 3); // 非テンプレートコンストラクタから生成された #3 が使われる template <class T> A(T) -> A<T>; // #6, #5 に比べて特殊でない A a(42); // #6 で A<int> と推論され #1 で初期化される A b = a; // #5 で A<int> と推論され #2 で初期化される template <class T> A(A<T>) -> A<A<T>>; // #7, #5 と同程度に特殊 A b2 = a; // #7 で A<A<int>> と推論され #1 で初期化される- 例終わり ]
#7 の振る舞いについて確認する必要がある。何故 #5 に打ち勝つのか?
上記の二項関係は「より良い」という字面に反していいかげんな関係である。
つまり better(F, G) := P1(F, G) || ... || Pn(F, G)
(但し P1, ..., Pn
は前順序を与える?) の形式をしているが、
この時 better(F, G)
と worse(F, G) := better(G, F)
は排他的にはなっていない。
つまり、互いに他方よりも良くかつ悪いという場合がある (全順序律を満たさない)。
もちろん、互いに他方より良くも悪くもないという場合もある (反対称律を満たさない)。
推移律はどうか? うーん…もう少し後でちゃんと考える必要がある…。
2 他の全ての呼び出し可能関数よりも良い呼び出し可能関数が一意に存在する場合、 それが多重定義解決によって選ばれる。それ以外の場合はその呼出は不適格である132。 [例:
void Fcn(const int*, short); void Fcn(int*, int); int i; short s = 0; void f() { Fcn(&i, s); // 曖昧。何故なら &i → int* は &i → const int* より良く、 // 同時に s → short が s → int より良い。 Fcn(&i, 1L); // Fcn(int*, int) が呼び出される。何故なら &i → int* は &i → const int* より良く、 // 1L → short と 1L → int はどちらが良いわけでもない。 Fcn(&i, 'c'); // Fcn(int*, int) が呼び出される。何故なら &i → int* は &i → const int* より良く、 // c → int は c → short より良い。 }
- 例終わり ]
3 最良の呼び出し可能関数が複数の宣言を持つ関数に決まった場合、 関数を呼び出し可能にした或る既定の実引数を 2つ以上の宣言 (または using 宣言の場合、それが指し示す宣言) が指定したとき プログラムは不適格である。[例:
namespace A { extern "C" void f(int = 5); } namespace B { extern "C" void f(int = 5); } using A::f; using B::f; void use() { f(3); // OK, 呼び出し可能であるために既定の実引数は使われなかった f(); // Error: 既定の実引数が2回見つかった }
- 例終わり ]
原文 a default argument that made the function viable は微妙。 Viable functions の所では m+1 番目の既定の実引数についてしか述べられていない。 しかし、ここでは m+1 番目以降の全ての実引数について述べているはずである (不定冠詞 a が用いられているのはそれを示唆する)。
extern "C"
がついているので、
A::f
と B::f
は同一の関数?
と思ったがそのようなことは何処かに書かれていただろうか?
footnote 131 関数が静的メンバ関数の場合は、第一引数 (つまり暗黙オブジェクト実引数) は、 その関数が他の関数より良いか悪いかの判断には寄与しないことを表す。
footnote 132
最適な呼び出し可能関数の決定アルゴリズムは呼び出し可能関数の数について線形時間になる。
単純な勝ち抜き戦によってどの対戦相手と比べても悪くない関数 W
を決める。
W
と直接対戦しなかった関数 F
が
W
より悪くないという可能性もあるが、
F
が最終的に残っていないということから
勝ち抜き戦の途中で F
が
F
より悪くない別の関数 G
と対戦しているはずなので、
F
は最良の呼び出し可能関数にはなりえない。
従って W
が最良の呼び出し可能関数であるか、そのようなものは存在しないかである。
そこで呼び出し可能関数に対して2回目の走査を行い
W
が他の全ての呼び出し可能関数より良いかどうかを確かめる。
より良いか悪いかは変な二項関係なので2回目の走査は必要である。
1 Define ICSi(F) as follows:
Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then
struct A { A(); operator int(); operator double(); } a; int i = a; // a.operator int() followed by no conversion is better than // a.operator double() followed by a conversion to int float x = a; // ambiguous: both possibilities require conversions, // and neither is better than the other—end example ] or, if not that,
template <class T> struct A { operator T&(); // #1 operator T&&(); // #2 }; typedef int Fn(); A<Fn> a; Fn& lf = a; // calls #1 Fn&& rf = a; // calls #2—end example ] or, if not that,
template <class T> struct A { using value_type = T; A(value_type); // #1 A(const A&); // #2 A(T, T, int); // #3 template<class U> A(int, T, U); // #4 // #5 is the copy deduction candidate, A(A) }; A x(1, 2, 3); // uses #3, generated from a non-template constructor template <class T> A(T) -> A<T>; // #6, less specialized than #5 A a(42); // uses #6 to deduce A<int> and #1 to initialize A b = a; // uses #5 to deduce A<int> and #2 to initialize template <class T> A(A<T>) -> A<A<T>>; // #7, as specialized as #5 A b2 = a; // uses #7 to deduce A<A<int>> and #1 to initialize—end example ]
2 If there is exactly one viable function that is a better function than all other viable functions, then it is the one selected by overload resolution; otherwise the call is ill-formed. 132 [Example:
void Fcn(const int*, short); void Fcn(int*, int); int i; short s = 0; void f() { Fcn(&i, s); // is ambiguous because &i → int* is better than &i → const int* // but s → short is also better than s → int Fcn(&i, 1L); // calls Fcn(int*, int), because &i → int* is better than &i → const int* // and 1L → short and 1L → int are indistinguishable Fcn(&i, 'c'); // calls Fcn(int*, int), because &i → int* is better than &i → const int* // and c → int is better than c → short }
—end example ]
3 If the best viable function resolves to a function for which multiple declarations were found, and if at least two of these declarations — or the declarations they refer to in the case of using-declarations — specify a default argument that made the function viable, the program is ill-formed. [Example:
namespace A { extern "C" void f(int = 5); } namespace B { extern "C" void f(int = 5); } using A::f; using B::f; void use() { f(3); // OK, default argument was not used for viability f(); // Error: found default argument twice }
—end example ]
footnote 131 If a function is a static member function, this definition means that the first argument, the implied object argument, has no effect in the determination of whether the function is better or worse than any other function.
footnote 132 The algorithm for selecting the best viable function is linear in the number of viable functions. Run a simple tournament to find a function W that is not worse than any opponent it faced. Although another function F that W did not face might be at least as good as W , F cannot be the best function because at some point in the tournament F encountered another function G such that F was not better than G . Hence, W is either the best function or there is no best function. So, make a second pass over the viable functions to verify that W is better than all other functions.
1 暗黙変換列 (implicit conversion sequence) は、 実引数を対応する仮引数の型に変換するための型変換の列である。 変換列は Clause 7 で定義される暗黙変換になる。 つまり、単一の式によるオブジェクトまたは参照の初期化 (11.6, 11.6.3) である。
2 暗黙変換列では、実引数の型・cv修飾・値分類と、 それらが仮引数の対応する性質に一致するように変換する方法のみを考慮する。 実引数の寿命・記憶域クラス・アライメント・アクセス可能性、 実引数がビットフィールドかどうか、 関数が削除されている (11.4.3) かどうかといった性質は考慮されない。 従って、或る実引数と仮引数の組に対して暗黙変換列が定義されたとしても、 その実引数から仮引数への変換が最終的な解析で不適格となる可能性は残る。
3 適格な暗黙変換列は以下の内の何れかである:
4 但し、変換先が
であり、そのコンストラクタまたはユーザ定義の変換関数が
X
のコンストラクタの第一仮引数であり、
その型が X
または "cv X
の参照"
であるとき、ユーザ定義の変換列は考慮されない。 [註: ここにある規則は多重定義解決において複数のユーザ定義変換が起こること、 乃至は無限再帰を防ぐためにある。 - 註終わり ] [例:
struct Y { Y(int); }; struct A { operator int(); }; Y y1 = A(); // error: A::operator int() は候補ではない。 struct X { }; struct B { operator X(); }; B b; X x({b}); // error: B::operator X() は候補ではない。
2つ目の例は 16.3.3.1/(4.5) の例なのだと思われるが、 X x({b}) は {{b}} という初期化リストと解釈されるということなのか。■
- 例終わり ]
5 仮引数の型が参照のときは 16.3.3.1.4 を見よ。
6
仮引数の型が参照でないとき、暗黙変換列は実引数の式による仮引数のコピー初期化をモデル化する。
暗黙変換列は、特に、実引数の式を仮引数の型の prvalue に変換するのに必要なコピー初期化である。
[註: 仮引数がクラス型の場合、これはこの章 Clause 16 のために定義される概念上の変換である。
実際の初期化はコンストラクタによって定義され、これは変換ではない。- 註終わり ]
一番外側の cv 修飾の違いは最終的な初期化で考慮されるので変換列には寄与しない。
[例: 型 A
の仮引数は const A
の実引数で初期化できる。
このとき暗黙変換列は恒等変換であり、const A
から
A
への変換は含まない。 - 例終わり ]
仮引数がクラス型を持ち実引数の式が同じ型を持つとき、暗黙変換列は恒等変換である。
仮引数がクラス型を持ち実引数の式が派生クラスの型を持つとき、
暗黙変換列は、派生クラスから基底クラスへの derived-to-base Conversion である。
[註: そのような標準返還はない。derived-to-base Conversion は暗黙変換列を記述するためだけに存在する。 - 註終わり ]
derived-to-base Conversion は Conversion ランクを持つ (16.3.3.1.1)。
7 全ての文脈で、暗黙オブジェクト仮引数または代入操作の左辺に変換するとき、標準変換のみが許される。
8 実引数を仮引数の型に一致させるのに変換が必要ない場合、 暗黙変換列は恒等変換 (16.3.3.1.1) からなる標準変換列である。
9 実引数を仮引数の型に一致させる変換の列が存在しないとき、暗黙変換列は構築できない。
10 実引数を仮引数の型に変換する変換の列として異なる複数のものが考えられるとき、 その仮引数の暗黙変換列はそれらの列を総称する単一の変換列として定義し、 曖昧な変換列 (ambiguous conversion sequence) と呼ぶ。 16.3.3.2 での暗黙変換列のランク付けにおいて、 曖昧な変換列はユーザ定義の変換列として扱われ、 他のユーザ定義変換列と比較不能とする。 [註: この規則は、仮引数の曖昧な変換列により、 関数が呼び出し可能でなくなるのを防ぐためにある。[例:
class B; class A { A (B&);}; class B { operator A (); }; class C { C (B&); }; void f(A) { } void f(C) { } B b; f(b); // 不適格: コンストラクタを通した変換 b → C と、 // コンストラクタまたは変換関数を通した曖昧な変換 b → A があるので曖昧 void f(B) { } f(b); // OK, 曖昧さはない
- 例終わり ] - 註終わり ] 曖昧な変換列を持つ関数が最適な呼び出し可能関数に選ばれた場合、 対応する実引数の変換が曖昧になるのでその関数呼び出しは不適格となる。
11 既に述べた暗黙変換列の3つの形式は続く節で定義される。
1 An implicit conversion sequence is a sequence of conversions used to convert an argument in a function call to the type of the corresponding parameter of the function being called. The sequence of conversions is an implicit conversion as defined in Clause 7, which means it is governed by the rules for initialization of an object or reference by a single expression (11.6, 11.6.3).
2 Implicit conversion sequences are concerned only with the type, cv-qualification, and value category of the argument and how these are converted to match the corresponding properties of the parameter. Other properties, such as the lifetime, storage class, alignment, accessibility of the argument, whether the argument is a bit-field, and whether a function is deleted (11.4.3), are ignored. So, although an implicit conversion sequence can be defined for a given argument-parameter pair, the conversion from the argument to the parameter might still be ill-formed in the final analysis.
3 A well-formed implicit conversion sequence is one of the following forms:
4 However, if the target is
and the constructor or user-defined conversion function is a candidate by
user-defined conversion sequences are not considered. [Note: These rules prevent more than one user-defined conversion from being applied during overload resolution, thereby avoiding infinite recursion. —end note ] [Example:
struct Y { Y(int); }; struct A { operator int(); }; Y y1 = A(); // error: A::operator int() is not a candidate struct X { }; struct B { operator X(); }; B b; X x({b}); // error: B::operator X() is not a candidate
—end example ]
5 For the case where the parameter type is a reference, see 16.3.3.1.4.
6 When the parameter type is not a reference, the implicit conversion sequence models a copy-initialization of the parameter from the argument expression. The implicit conversion sequence is the one required to convert the argument expression to a prvalue of the type of the parameter. [Note: When the parameter has a class type, this is a conceptual conversion defined for the purposes of Clause 16; the actual initialization is defined in terms of constructors and is not a conversion. —end note ] Any difference in top-level cv-qualification is subsumed by the initialization itself and does not constitute a conversion. [Example: A parameter of type A can be initialized from an argument of type const A . The implicit conversion sequence for that case is the identity sequence; it contains no “conversion” from const A to A . —end example ] When the parameter has a class type and the argument expression has the same type, the implicit conversion sequence is an identity conversion. When the parameter has a class type and the argument expression has a derived class type, the implicit conversion sequence is a derived-to-base Conversion from the derived class to the base class. [Note: There is no such standard conversion; this derived-to-base Conversion exists only in the description of implicit conversion sequences. —end note ] A derived-to-base Conversion has Conversion rank (16.3.3.1.1).
7 In all contexts, when converting to the implicit object parameter or when converting to the left operand of an assignment operation only standard conversion sequences are allowed.
8 If no conversions are required to match an argument to a parameter type, the implicit conversion sequence is the standard conversion sequence consisting of the identity conversion (16.3.3.1.1).
9 If no sequence of conversions can be found to convert an argument to a parameter type, an implicit conversion sequence cannot be formed.
10 If several different sequences of conversions exist that each convert the argument to the parameter type, the implicit conversion sequence associated with the parameter is defined to be the unique conversion sequence designated the ambiguous conversion sequence. For the purpose of ranking implicit conversion sequences as described in 16.3.3.2, the ambiguous conversion sequence is treated as a user-defined conversion sequence that is indistinguishable from any other user-defined conversion sequence. [Note: This rule prevents a function from becoming non-viable because of an ambiguous conversion sequence for one of its parameters. [Example:
[Example: class B; class A { A (B&);}; class B { operator A (); }; class C { C (B&); }; void f(A) { } void f(C) { } B b; f(b); // ill-formed: ambiguous because there is a conversion b → C (via constructor) // and an (ambiguous) conversion b → A (via constructor or conversion function) void f(B) { } f(b); // OK, unambiguous
—end example ] —end note ] If a function that uses the ambiguous conversion sequence is selected as the best viable function, the call will be ill-formed because the conversion of one of the arguments in the call is ambiguous.
11 The three forms of implicit conversion sequences mentioned above are defined in the following subclauses.
1
この章では より良い変換列 (better conversion sequence) と
より良い変換 (better conversion) に基いて暗黙変換列に半順序を定義する。
暗黙変換列 S1
が S2
より良い変換列である場合、
S2
は S1
と比べてより悪い変換列 (worse conversion sequence) であるという。
変換列 S1
が S2
に対してより良い変換列でもより悪い変換列でもないとき、
S1
と S2
は比較不能変換列 (indistinguishable conversion sequences) であるという。
indistinguishable は通常「区別できない」と訳すが、 実際の意味にそぐわないように思われるので、半順序の用語としての「比較不能」を用いることにした。
2 暗黙変換列の基本形 (16.3.3.1) を比較するとき、
3 同じ形の2つの暗黙変換列は、以下の規則が適用されなければ比較不能変換列である。
L1
はリスト初期化列 L2
より良い変換列である:
L1
について或る X
が存在して
std::initializer_list<X>
への変換列であって、
L2
がそうでないときか、そうでなければL1
が N1
個の T
の配列への変換列で、
L2
が N2
個の T
の配列への変換列であって、
N1
が N2
よりも小さいとき。
void f1(int); // #1 void f1(std::initializer_list<long>); // #2 void g1() { f1({42}); } // #2 が選ばれる void f2(std::pair<const char*, const char*>); // #3 void f2(std::initializer_list<std::string>); // #4 void g2() { f2({"foo","bar"}); } // #4 が選ばれる- 例終わり ]
「この段落の他の規則が仮に適用可能だったとしても (原文 even if one of the other rules in this paragraph would otherwise apply)」 が何を言いたいのか良くわからない。
S1
は標準変換列 S2
より良い変換列である。
S1
は S2
の真部分列である
(16.3.3.1.1 で定義される正準形で比較する。但し Lvalue Transformation はしない。
恒等変換列は任意の非恒等な変換列の部分列と考える) か、そうでなければ、S1
のランクが S2
のランクより良いか、
S1
と S2
のランクが同じで次の段落の規則によって比較可能の場合か、
そうでなければ、S1
と S2
が参照束縛 (11.6.3) であり、
どちらも ref-qualifier のない非静的メンバ関数の暗黙オブジェクト仮引数ではなく、
S1
が右辺値参照を rvalue に束縛し、
S2
が左辺値参照を束縛する [例:
int i; int f1(); int&& f2(); int g(const int&); int g(const int&&); int j = g(i); // g(const int&) が呼び出される int k = g(f1()); // g(const int&&) が呼び出される int l = g(f2()); // g(const int&&) が呼び出される struct A { A& operator<<(int); void p() &; void p() &&; }; A& operator<<(A&&, char); A() << 1; // A::operator<<(int) が呼び出される A() << 'c'; // operator<<(A&&, char) が呼び出される A a; a << 1; // A::operator<<(int) が呼び出される a << 'c'; // A::operator<<(int) が呼び出される A().p(); // A::p()&& が呼び出される a.p(); // A::p()& が呼び出される- 例終わり ] か、そうでなければ、
S1
and S2
が参照束縛 (11.6.3) であり、
S1
が左辺値参照を関数の lvalue に束縛し
S2
が右辺値参照を関数の lvalue に束縛する [例:
int f(void(&)()); // #1 int f(void(&&)()); // #2 void g(); int i1 = f(g); // #1 が呼び出される。- 例終わり ] か、そうでなければ、
右辺値参照は関数の lvalue に束縛できる (11.6.3/(5.2.1.1), 16.3.3.1.4/3)。
S1
と S2
が修飾変換のみにおいて異なり、
それぞれ類似の型 T1
と T2
(7.5) を生成し、
T1
の cv 修飾が T2
の cv 修飾の真部分集合を為す [例:
int f(const volatile int *); int f(const int *); int i; int j = f(&i); // f(const int*) が呼び出される- 例終わり ] か、そうでなければ、
S1
と S2
が参照束縛 (11.6.3) で、
参照の示す先が一番外側の cv 修飾を除いて同じ型であり、
S2
で初期化される参照の指し示す型が、
S1
で初期化される参照の指し示す型に比べてより cv 修飾されている。[例:
int f(const int &); int f(int &); int g(const int &); int g(int); int i; int j = f(i); // f(int &) が呼び出される int k = g(i); // 曖昧 struct X { void f() const; void f(); }; void g(const X& a, X b) { a.f(); // X::f() const が呼び出される b.f(); // X::f() が呼び出される }- 例終わり ]
U1
はもう一つのユーザ定義変換列 U2
に比べてより良い変換列である。
U1
と U2
が同じユーザ定義変換関数・コンストラクタを含むか同じクラスを集成体初期化するとき、
U1
に2つ目の標準変換列が U2
の2つ目の標準変換列よりも良い。[例:
struct A { operator short(); } a; int f(int); int f(float); int i = f(a); // f(int) が呼び出される。short → int の方が // short → float より良いため- 例終わり ]
4 標準変換列はそのランクで順序付けられる。 Exact Match は Promotion より良い変換であり、 Promotion は Conversion より良い変換である。 同じランクの2つの変換列は、以下の規則が適用されない場合は比較不能である:
std::nullptr_t
から bool
への変換に比べて、
それ以外の変換はより良い変換である。B
がクラス A
から直接もしくは間接に派生するとき、
B*
から A*
への変換と
A*
から void*
への変換は、
共に B*
から void*
への変換より良い。B
がクラス A
から直接もしくは間接に派生し、
クラス C
がクラス B
から直接もしくは間接に派生するとき、
C*
から B*
への変換は
C*
から A*
への変換より良く、[例:
struct A {}; struct B : public A {}; struct C : public B {}; C* pc; int f(A*); int f(B*); int i = f(pc); // f(B*) が呼び出される。- 例終わり ]
C
の式を B
への参照に束縛するのは、
型 C
の式を A
への参照に束縛するのより良く、
束縛の対象と束縛先が反転している気がする。16.3.3.2/(4.4.6) も同様。
A::*
から B::*
の変換は、
A::*
から C::*
の変換より良く、C
から B
の変換は、
C
から A
の変換より良く、B*
から A*
への変換は
C*
から A*
への変換より良く、C
の式を B
への参照に束縛するのは、
型 C
の式を A
への参照に束縛するのより良く、B::*
から C::*
への変換は
A::*
から C::*
への変換より良く、B
から A
の変換は、
C
から A
の変換より良い。1 This subclause defines a partial ordering of implicit conversion sequences based on the relationships better conversion sequence and better conversion. If an implicit conversion sequence S1 is defined by these rules to be a better conversion sequence than S2, then it is also the case that S2 is a worse conversion sequence than S1. If conversion sequence S1 is neither better than nor worse than conversion sequence S2, S1 and S2 are said to be indistinguishable conversion sequences.
2 When comparing the basic forms of implicit conversion sequences (as defined in 16.3.3.1)
3 Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of the following rules applies:
void f1(int); // #1 void f1(std::initializer_list<long>); // #2 void g1() { f1({42}); } // chooses #2 void f2(std::pair<const char*, const char*>); // #3 void f2(std::initializer_list<std::string>); // #4 void g2() { f2({"foo","bar"}); } // chooses #4—end example ]
int i; int f1(); int&& f2(); int g(const int&); int g(const int&&); int j = g(i); // calls g(const int&) int k = g(f1()); // calls g(const int&&) int l = g(f2()); // calls g(const int&&) struct A { A& operator<<(int); void p() &; void p() &&; }; A& operator<<(A&&, char); A() << 1; // calls A::operator<<(int) A() << 'c'; // calls operator<<(A&&, char) A a; a << 1; // calls A::operator<<(int) a << 'c'; // calls A::operator<<(int) A().p(); // calls A::p()&& a.p(); // calls A::p()&—end example ] or, if not that,
int f(void(&)()); // #1 int f(void(&&)()); // #2 void g(); int i1 = f(g); // calls #1—end example ] or, if not that,
int f(const volatile int *); int f(const int *); int i; int j = f(&i); // calls f(const int*)—end example ] or, if not that,
int f(const int &); int f(int &); int g(const int &); int g(int); int i; int j = f(i); // calls f(int &) int k = g(i); // ambiguous struct X { void f() const; void f(); }; void g(const X& a, X b) { a.f(); // calls X::f() const b.f(); // calls X::f() }—end example ]
struct A { operator short(); } a; int f(int); int f(float); int i = f(a); // calls f(int), because short → int is // better than short → float.—end example ]
4 Standard conversion sequences are ordered by their ranks: an Exact Match is a better conversion than a Promotion, which is a better conversion than a Conversion. Two conversion sequences with the same rank are indistinguishable unless one of the following rules applies:
struct A {}; struct B : public A {}; struct C : public B {}; C* pc; int f(A*); int f(B*); int i = f(pc); // calls f(B*)—end example ]
略
略
略