[解決済み] ニエブロイドとは?
質問
C++20では、cppreferenceでquot;niebloid"という用語をより頻繁に読むことができるようになりました。
SOでは、今日2020/07/16に2つの記事がそれに言及しているのが見つかりました。
Googleもそれほど多くの結果を吐き出すわけではありません。最も顕著なのは、おそらく ここで .
誰かニーブロイドにもう少し光を当ててくれませんか?
どのように解決するのですか?
用語
ニエブロイド
の由来は
エリック・ニーブラー(Eric Niebler)の
という名前からきています。簡単に言うと、ADL(引数依存参照)を無効にする関数オブジェクトで、これにより
std::
のオーバーロードが拾われないようにするための関数オブジェクトです。
std::ranges
のアルゴリズムが呼び出されたときに拾われない。
のツイート(2018年)と回答はこちらです。 エリック 自身 という名前にしました。エリックが書いた 記事 を2014年に書き、このコンセプトを説明しています。
で最もよく見ることができます。 規格の文書そのものです。 :
25.2.2
で定義されたエンティティはstd::ranges
の名前空間は、引数依存の名前検索では見つかりません ( 基本.lookup.argdep ). 非限定型( 基本.lookup.unqual ) 名前検索で見つかった場合、それらは引数依存の名前検索を抑制します。void foo() { using namespace std::ranges; std::vector<int> vec{1,2,3}; find(begin(vec), end(vec), 2); // #1 }
での関数呼び出し式は
#1
で呼び出されるstd::ranges::find
ではなくstd::find
にもかかわらず、(a)イテレータの型がbegin(vec)
とend(vec)
が関連付けられている可能性があります。namespace std
と、(b)std::find
は、より特化された([temp.func.order])std::ranges::find
というのは、前者は最初の2つのパラメータが同じ型であることを必要とするからです。
上記の例では
ADL
がオフになっているので、呼び出しは直接
std::ranges::find
.
これをさらに探求するために、小さな例を作ってみましょう。
namespace mystd
{
class B{};
class A{};
template<typename T>
void swap(T &a, T &b)
{
std::cout << "mystd::swap\n";
}
}
namespace sx
{
namespace impl {
//our functor, the niebloid
struct __swap {
template<typename R, typename = std::enable_if_t< std::is_same<R, mystd::A>::value > >
void operator()(R &a, R &b) const
{
std::cout << "in sx::swap()\n";
// swap(a, b);
}
};
}
inline constexpr impl::__swap swap{};
}
int main()
{
mystd::B a, b;
swap(a, b); // calls mystd::swap()
using namespace sx;
mystd::A c, d;
swap(c, d); //No ADL!, calls sx::swap!
return 0;
}
説明文は cppreference :
このページで説明されている機能的な実体は、ニーブロイドである、ということです。
- 明示的なテンプレート引数リストは、それらのいずれかを呼び出す際に指定してはならない。
- どれも引数依存のルックアップでは見えない。
- それらのいずれかが、関数呼び出し演算子の左側にある名前の通常の非限定検索によって見つかった場合、引数依存の検索を抑制します。
ニーブロイドは関数オブジェクトであるため、引数依存参照(ADL)では見えません。3つ目のポイントは、標準の例で起こったことです。
find(begin(vec), end(vec), 2); //unqualified call to find
の呼び出しは
find()
の呼び出しは修飾されていないので、ルックアップが始まると
std::ranges::find
関数オブジェクトを見つけ、それがADLの発生を止めることになります。
さらに検索してみると この が、ニーブロイドとCPO(カスタマイズ ポイント オブジェクト)についての最もわかりやすい説明だと思います。
... a CPO はオブジェクト(関数ではない)であり、呼び出し可能であり、constexpr-constructable であり、[...] カスタマイズ可能であり(これが「プログラム定義型と相互作用する」という意味です)、概念制約付きであることです。
[...]
上記から「カスタマイズ可能、概念に縛られる」という形容詞を取り除くと、ADLをオフにする機能オブジェクトができます - しかし、必ずしもカスタマイズのポイントではありません . C++2a Ranges アルゴリズムのようなstd::ranges::find
は,このようなものである. 呼び出し可能で constexpr で構成可能なオブジェクトは、俗に "ニーブロ" と呼ばれます。 Eric Nieblerに敬意を表して。
関連
-
[解決済み】C++ - 解放されるポインタが割り当てられていないエラー
-
[解決済み】「Expected '(' for function-style cast or type construction」エラーの意味とは?
-
[解決済み] to_string は std のメンバーではない、と g++ が言っている (mingw)
-
[解決済み] explicit キーワードの意味は?
-
[解決済み] ルール・オブ・スリーとは?
-
[解決済み] コピーアンドスワップ慣用句とは?
-
[解決済み] スマートポインターとは何ですか?
-
[解決済み] ムーブセマンティクスとは何ですか?
-
[解決済み] C++でextern "C "を使用した場合の効果は?
-
[解決済み】C/C++の"-->"演算子とは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】非静的メンバ関数への参照を呼び出す必要がある
-
[解決済み] エラーが発生する。ISO C++は型を持たない宣言を禁じています。
-
[解決済み】C++のGetlineの問題(オーバーロードされた関数 "getline "のインスタンスがない
-
[解決済み】文字列関数で'char const*'のインスタンスを投げた後に呼び出されるterminate [閉店].
-
[解決済み】関数名の前に期待されるイニシャライザー
-
[解決済み】Visual Studio 2013および2015でC++コンパイラーエラーC2280「削除された関数を参照しようとした」が発生する
-
[解決済み】1つ以上の多重定義されたシンボルが見つかる
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み] スタックアロケーションにより初期化されていない値が作成された