話を続けると、std::initializer_list
代わりに単一のパラメーターを使用して、アクセス関数のオーバーロードを作成できることに気付きました。
class array_md
{
//...
my_type & operator []( size_type i )
{ /* Lots of code */ }
my_type const & operator []( size_type i ) const
{ /* same Lots of code, with "const" sprinkled in */ }
my_type & operator []( std::initializer_list<size_type> i )
{ /* Lots of different code */ }
my_type const & operator []( std::initializer_list<size_type> i ) const
{ /* same Lots of different code, with "const" sprinkled in */ }
//...
};
私のバージョンでは、次のものat
があります。
class array_md
{
//...
template < typename ...Index >
complicated & at( Index &&...i ) // (1)
{ /* Lots of code */ }
template < typename ...Index >
complicated const & at( Index &&...i ) const // (2)
{ /* same Lots of code, with "const" sprinkled in */ }
my_type & at( std::initializer_list<size_type> i ) // (3)
{ /* Lots of different code */ }
my_type const & at( std::initializer_list<size_type> i ) const // (4)
{ /* same Lots of different code, with "const" sprinkled in */ }
//...
};
(イニシャライザ リストのエントリの量によって型を変更できないのは実行時であるため、戻り値の型を修正し、エントリの数が間違っている場合はスローします。) 新しいオーバーロードのコードは次のとおりです。mutable
とのバージョンで繰り返す必要があるため、const
コードを保存する方法を考えています。私は混乱しようとしましたconst_cast
:
class array_md
{
//...
my_type & operator []( size_type i );
my_type const & operator []( size_type i ) const;
my_type & operator []( std::initializer_list<size_type> i )
{
return const_cast<my_type &>( const_cast<array_md const
*>(this)->operator [](i) );
}
my_type const & operator []( std::initializer_list<size_type> i ) const;
//...
};
ここでは、3 番目のバージョンが 4 番目のバージョンを呼び出し、const_cast
コンパイラの苦情を回避するために使用しています。(最初に平手打ちしたものから削除しているので、トレスパスは問題ありconst
ません。依存関係を逆にしないでください。mutable
真のオブジェクトでメンバー関数を呼び出すことになる可能性がありconst
ます!) at
(3)とマークされたオーバーロードを(4)とマークされたオーバーロードを実装します。しかし、 の代替候補が 3 つあるためat
、代わりに (2) が選択されるというエラーが発生しました。ユニバーサルオーバーロードと比較して完全一致を引き起こさないstd::initializer_list
内部呼び出しに(値で)渡す方法に何かありますか? at
私は普遍的なメソッドの競合を抱えている古くからの友人です。
TL;DR : サンプル コードはstd::initializer_list
、関数パラメーター リストで値によって取得されるオブジェクトを示しています。それは、それらを渡す際のコンパイラの最初の優先事項ですか? それとも参照によるものですか?これは、完全一致が必要な場合 (普遍的なオーバーロードを無効にするため) に重要です。