13
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C++Advent Calendar 2024

Day 4

Niebloid の導入と廃止

Posted at

Niebloid とは?

Niebloid とは、 std::ranges の元になったライブラリ range-v3 の作者である Eric Niebler さんの名前をもじった、C++ における「ADL(argument dependent lookup)を引き起こさない関数テンプレートのような何か」を指す言葉です。

この niebloid という概念は C++20 にて暗黙的に導入され、 C++26 で廃止されることになりました。一体何があったのでしょうか。

Niebloid の導入

C++20 では <algorithm> ヘッダに既存のアルゴリズムと同名のものが std::ranges 名前空間以下に追加されました。

namespace std {

  template <class I>
  auto reverse(I, I);  // #1

  namespace ranges {

    template <class I, class S>
    auto reverse(I, S);  // #2

    template <class R>
    auto reverse(R&&);

  }  // namespace ranges

}  // namespace std

このとき以下のような呼び出しを行うと、#1 と #2 のいったいどちらが呼び出されるのでしょうか。

template <class R>
void func(R&& r) {
  using namespace std::ranges;

  reverse(begin(r), end(r));  // std::ranges::reverse を呼んでほしい
}

もし begin(r)end(r) の型が std 名前空間になければ、見えている関数は std::ranges::reverse だけなのでそちらが呼び出されますが、std 名前空間に含まれている場合は ADL によって std::reverse も候補に入り、もし2つの型が同じならば #1 の関数が優先されてしまい、これは意図通りではありません。

もしここで reverse が関数オブジェクトとして実装されていたとすれば、 ADL は関数や関数テンプレートに対してしか働かないので問題は解決しますが、かといって C++ 標準規格としては今まで通り関数テンプレートとしてアルゴリズムを規定したいという思いがあり、そこで niebloid が導入されました。(明示的に niebloid という語が規格に導入されたわけではありませんが)

Niebloid の廃止

こうして導入された niebloid ですが、各処理系がそのような特殊な機能を用意したわけではなく、結局のところ関数オブジェクトとして実装されていました。1

そして関数オブジェクトではないかもしれないことによるデメリットとして、関数オブジェクトを引数に取る関数には niebloid を直に渡せないことがあります。

// std::ranges::distance は niebloid なので…

// 動かない「かも」しれないコード
auto x = std::views::transform(r, std::ranges::distance);

// 「正しい」呼び出し
auto y = std::views::transform(r, [](auto&& v) { return std::ranges::distance(v); });  

これらのことから標準化委員会も niebloid とするデメリットの方が大きいと考えたようで、C++26 では前述のアルゴリズムたちを関数オブジェクトとすることになりました。2

あとがき

多くのユーザーにとってこの変更は気づかないほど些細なものです。
しかし C++26 からは std::ranges 以下の関数群を気兼ねなく関数オブジェクトとして引数に投げられますね。

嬉しい!

参照

  1. MSVC では niebloid をわざわざコピー・ムーブ不可としてオブジェクトとしての使用を禁じていました

  2. P3136R0 Retiring niebloids

13
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?