function() noexcept; // (1) C++11
function(nullptr_t) noexcept; // (2) C++11
function(const function& f); // (3) C++11
function(function&& f); // (4) C++11
function(function&& f) noexcept; // (4) C++20
template <class F>
function(F f); // (5) C++11
template <class F>
function(F&& f); // (5) C++23
template <class Alloc>
function(allocator_arg_t, const Alloc& alloc) noexcept; // (6) C++17で削除
template <class Alloc>
function(allocator_arg_t, const Alloc& alloc, nullptr_t) noexcept; // (7) C++17で削除
template <class Alloc>
function(allocator_arg_t, const Alloc& alloc, const function& f); // (8) C++17で削除
template <class Alloc>
function(allocator_arg_t, const Alloc& alloc, function&& f); // (9) C++17で削除
template <class F, class Alloc>
function(allocator_arg_t, const Alloc& alloc, F f); // (10) C++17で削除
概要
functionオブジェクトを構築する。
- (1) : デフォルト構築。空の
functionオブジェクトを構築する - (2) :
nullptrからの構築。空のfunctionオブジェクトを構築する - (3) : コピー構築する
- (4) : ムーブ構築する
- (5) : 任意の型の関数ポインタ、メンバポインタ、関数オブジェクトを受け取って構築する
- (6) : アロケータをとって空の
functionオブジェクトを構築する - (7) : アロケータと
nullptrをとって空のfunctionオブジェクトを構築する - (8) : アロケータをとってコピー構築する
- (9) : アロケータをとってムーブ構築する
- (10) : アロケータと、任意の型の関数ポインタ、メンバポインタ、関数オブジェクトを受け取って構築する
テンプレートパラメータ制約
decay_t<F>をFDとして、
- (5) :
- (10) :
適格要件
- (5) :
- C++11
Fはコピー構築可能であることFは、パラメータとしてArgTypes...型をとり、戻り値としてR型を返す関数ポインタ、メンバ関数ポインタ、メンバ変数ポインタ、または関数オブジェクトであること。
- C++23
FDはコピー構築可能であることFDはFから構築可能であること
- C++11
効果
- (1), (2) : 関数を持たない空の
functionオブジェクトを構築する。この方法で構築した後、operator boolはfalseを返す。 - (3) :
fが保持する関数、または関数オブジェクトをコピーする。 - (4) :
fが保持する状態を*thisに移動する。移動された後のfは、未規定な値を持つ有効な状態となる。 - (5) :
fがヌルの関数ポインタ、もしくはメンバポインタである場合、構築後のoperator boolはfalseを返す。fが有効な関数ポインタ、メンバポインタ、もしくは関数オブジェクトである場合は、fが持つターゲットを*thisに移動する。 - (6), (7) : アロケータを設定し、関数を持たない空の
functionオブジェクトを構築する。この方法で構築した後、operator boolはfalseを返す。 - (9) : アロケータを設定し、
fが保持する状態を*thisに移動する。移動された後のfは、未規定な値を持つ有効な状態となる。 - (10) : アロケータを設定する。
fがヌルの関数ポインタ、もしくはメンバポインタである場合、構築後のoperator boolはfalseを返す。fが有効な関数ポインタ、メンバポインタ、もしくは関数オブジェクトである場合は、fが持つターゲットを*thisに移動する。
例外
- (3) :
- C++11
fのターゲットがreference_wrapper経由で渡された呼び出し可能オブジェクト、もしくは関数ポインタである場合は、例外を投げない- そうでない場合は、
bad_allocや、格納された呼び出し可能オブジェクトのコピーコンストラクタが投げる例外を送出する可能性がある
- C++17
- 例外を投げない条件が、
fのターゲットがreference_wrapperの特殊化、もしくは関数ポインタである場合として規定された
- 例外を投げない条件が、
- C++11
- (4) :
- C++11
- 例外に関する規定はない
- C++17
fのターゲットがreference_wrapperの特殊化、もしくは関数ポインタである場合は、例外を投げない- そうでない場合は、
bad_allocや、格納された呼び出し可能オブジェクトのコピーコンストラクタ/ムーブコンストラクタが投げる例外を送出する可能性がある
- C++20
- 保持する対象によらず
noexceptである
- 保持する対象によらず
- C++11
- (8) :
- C++11 : (3)のC++11の規定と同じ
- (10) :
備考
- (5), (10) :
削除の詳細
- (6)-(10) : このクラスのメモリアロケータサポートは、ほとんどの標準ライブラリ実装で使用されず、メモリアロケータを使用する必要がなかった。そのため、実装もされなかったことでユーザーにも使われてこなかったため、この機能を削除した。
例
#include <cassert>
#include <iostream>
#include <functional>
#include <utility>
struct ident_functor {
int operator()(int x) const
{ return x; }
};
int ident_func(int x)
{ return x; }
struct X {
int value;
X() : value(3) {}
int ident_member_func(int x) const
{ return x; }
};
int main()
{
// (1)
// デフォルトコンストラクタ
// 空のfunctionオブジェクトを作る
{
std::function<int(int)> f;
assert(!f);
}
// (2)
// ヌルポインタを受け取るコンストラクタ
// デフォルトコンストラクタと同様、空のfunctionオブジェクトを作る
{
std::function<int(int)> f = nullptr;
assert(!f);
}
// (3)
// コピー構築
{
std::function<int(int)> f = ident_functor();
std::function<int(int)> g = f;
int result = g(1);
std::cout << "(3) : " << result << std::endl;
}
// (4)
// ムーブ構築
{
std::function<int(int)> f = ident_functor();
std::function<int(int)> g = std::move(f);
int result = g(1);
std::cout << "(4) : " << result << std::endl;
}
// (5)
// 関数ポインタを受け取って構築
{
std::function<int(int)> f = ident_func;
int result = f(1);
std::cout << "(5) function pointer : " << result << std::endl;
}
// (5)
// 関数オブジェクトを受け取って構築
{
std::function<int(int)> f = ident_functor();
int result = f(1);
std::cout << "(5) function object : " << result << std::endl;
}
// (5)
// メンバ関数ポインタを受け取った構築
{
std::function<int(const X&, int)> f = &X::ident_member_func;
X x;
int result = f(x, 1);
std::cout << "(5) member function pointer : " << result << std::endl;
}
// (5)
// メンバ変数ポインタを受け取った構築
{
std::function<int(const X&)> f = &X::value;
X x;
int result = f(x);
std::cout << "(5) member variable pointer : " << result << std::endl;
}
// (6)
// アロケータを受け取って空のfunctionオブジェクトを構築
{
// ※ここではint型を対象とするアロケータを渡しているが、内部で適切な関数の型にrebindして使われる。
std::function<int(int)> f(std::allocator_arg, std::allocator<int>());
assert(!f);
}
// (7)
// アロケータとヌルポインタを受け取って、空のfunctionオブジェクトを構築
{
std::function<int(int)> f(std::allocator_arg, std::allocator<int>(), nullptr);
assert(!f);
}
// (8)
// アロケータを受け取り、functionオブジェクトをコピー構築
{
std::function<int(int)> f = ident_functor();
std::function<int(int)> g(std::allocator_arg, std::allocator<int>(), f);
int result = g(1);
std::cout << "(8) : " << result << std::endl;
}
// (9)
// アロケータを受け取り、functionオブジェクトをムーブ構築
{
std::function<int(int)> f = ident_functor();
std::function<int(int)> g(std::allocator_arg, std::allocator<int>(), std::move(f));
int result = g(1);
std::cout << "(9) : " << result << std::endl;
}
// (10)
// 関数ポインタ、関数オブジェクト、メンバポインタのいずれかを受け取った構築
{
std::function<int(int)> f(std::allocator_arg, std::allocator<int>(), ident_functor());
int result = f(1);
std::cout << "(10) : " << result << std::endl;
}
}
出力
(3) : 1
(4) : 1
(5) function pointer : 1
(5) function object : 1
(5) member function pointer : 1
(5) member variable pointer : 3
(8) : 1
(9) : 1
(10) : 1
バージョン
言語
- C++11
処理系
- Clang: 3.0 ✅
- GCC: 4.3.6(アロケータを受け取るバージョンは、4.8.2時点でサポートされていない) ✅
- Visual C++: ??
参照
- N2308 Adding allocator support to
std::functionfor C++0x - LWG Issue 2132.
std::functionambiguity- C++14から、(5)と(10)でシグニチャが合わない関数オブジェクトが渡された場合に、SFINAEされるようになった。
- P0302R1 Removing Allocator Support in
std::function(rev 1) - LWG Issue 2393.
std::function's Callable definition is broken- C++17で、格納可能な要件がLvalue-Callable(
INVOKEを左辺値参照として行える型)として整理され、右辺値参照修飾の呼び出し演算子のみを持つ型は格納できないことが明確化された
- C++17で、格納可能な要件がLvalue-Callable(
- LWG Issue 2565.
std::function's move constructor should guarantee nothrow for reference_wrappers and function pointers- C++17で、ムーブコンストラクタ(4)も、
reference_wrapperか関数ポインタを保持する場合は例外を投げないことが規定された(コピーコンストラクタと同様の保証)
- C++17で、ムーブコンストラクタ(4)も、
- LWG Issue 2774.
std::functionconstruction vs assignment- C++23から、
function(F)のオーバーロードがfunction(F&&)に変更された
- C++23から、
- LWG Issue 2781. Contradictory requirements for
std::functionandstd::reference_wrapper- 例外を投げない対象が「
reference_wrapperの特殊化」である旨に文言が整理され、矛盾が解消された - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。矛盾した文言の修正であり、処理系の挙動は変わらないため
- 例外を投げない対象が「
- P0771R1 std::function move constructor should be noexcept
- LWG Issue 2850.
std::functionmove constructor does unnecessary work- ムーブコンストラクタの効果が「
*thisのターゲットが構築前のfのターゲットと等価になる」旨に緩和され、別途確保されたターゲットの所有権移動による最適化が許容された - この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。元の規定は主要な処理系の実際の動作(ヒープ上のターゲットはポインタを移動するだけ)と矛盾しており、規定を実装に合わせたものであるため
- ムーブコンストラクタの効果が「