std::type_info
単純なクラスですが、それを設定するには次のものが必要typeinfo
です: コンパイラ構造。
同様に、例外は通常のオブジェクトですが、例外をスローするにはコンパイラの魔法が必要です (例外はどこに割り当てられますか?)。
std::initializer_list
私にとっての疑問は、「コンパイラの魔法なしで sにどれだけ近づくことができるか?」ということです。
wikipediaを見るとstd::initializer_list<typename T>
、配列リテラルによく似たもので初期化できます。std::initializer_list<typename T>
配列を取る変換コンストラクター (つまり、 の単一の引数を取るコンストラクターT[]
)を指定してみましょう。
namespace std {
template<typename T> class initializer_list {
T internal_array[];
public:
initializer_list(T other_array[]) : internal_array(other_array) { };
// ... other methods needed to actually access internal_array
}
}
同様に、 a を使用するクラスstd::initializer_list
は、単一の引数を取るコンストラクstd::initializer_list
ター (別名変換コンストラクター)を宣言することによってこれを行います。
struct my_class {
...
my_class(std::initializer_list<int>) ...
}
だから行:
my_class m = {1, 2, 3};
コンパイラーに次のように考えさせます: 「 のコンストラクターを呼び出す必要がありmy_class
ます。C ++では2つの暗黙的なユーザー定義の変換を連鎖させることはできないと私に言う前の答え)。my_class
std::initializer_list<int>
int[]
int[]
std::initializer_list<int>
my_class
それで、これはどれくらい近いですか?まず、初期化子リストのいくつかの機能/制限がありません。私が強制しないことの 1 つは、イニシャライザ リストは配列リテラルでしか構築できないということです。一方、initializer_list
既に作成された配列も受け入れます。
int arry[] = {1, 2, 3};
my_class = arry;
さらに、右辺値参照をいじることはありませんでした。
最後に、このクラスは、コンパイラが 2 つのユーザー定義の変換を暗黙的に連鎖させた場合にのみ、新しい標準が示すように機能します。これは通常のケースでは特に禁止されているため、この例ではコンパイラの魔法が必要です。しかし、私は、(1) クラス自体は通常のクラスであり、(2) 関連する魔法 (「配列リテラル」初期化構文を強制し、2 つのユーザー定義の変換を暗黙的に連鎖できるようにする) は、見た目よりも少ないと主張します。一見。