std::is_function
From cppreference.com
| ヘッダ <type_traits> で定義 |
||
| template< class T > struct is_function; |
(C++11以降) | |
std::is_function は UnaryTypeTrait です。
T が関数型であるかをチェックします。std::function、ラムダ、operator() がオーバーロードされたクラス、関数へのポインタのような型は関数型とは見なされません。T が関数型の場合、true と等しいメンバー定数 value を提供します。それ以外の場合、value は false と等しくなります。
プログラムが std::is_function または std::is_function_v の特殊化を追加した場合、その動作は未定義です。
目次 |
[編集] テンプレートパラメータ
| T | - | チェックする型 |
[編集] ヘルパー変数テンプレート
| template< class T > constexpr bool is_function_v = is_function<T>::value; |
(C++17以降) | |
std::integral_constant から継承
メンバ定数
| value [static] |
T が関数型の場合に true、それ以外の場合に false(公開静的メンバ定数) |
メンバ関数
| operator bool |
オブジェクトを bool に変換し、value を返します。 (public member function) |
| operator() (C++14) |
value を返します。 (public member function) |
メンバ型
| 型 | 定義 |
value_type
|
bool |
type
|
std::integral_constant<bool, value> |
[編集] 備考
std::is_function は、はるかに単純な方法で実装できます。次の実装と同様の実装が、新しいバージョンの libc++、libstdc++、および MS STL で使用されています。
template<class T> struct is_function : std::integral_constant< bool, !std::is_const<const T>::value && !std::is_reference<T>::value > {};
以下に示す実装は、関数型の無数の種類を示すため、教育目的のものです。
[編集] 考えられる実装
// primary template template<class> struct is_function : std::false_type {}; // specialization for regular functions template<class Ret, class... Args> struct is_function<Ret(Args...)> : std::true_type {}; // specialization for variadic functions such as std::printf template<class Ret, class... Args> struct is_function<Ret(Args......)> : std::true_type {}; // specialization for function types that have cv-qualifiers template<class Ret, class... Args> struct is_function<Ret(Args...) const> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile> : std::true_type {}; // specialization for function types that have ref-qualifiers template<class Ret, class... Args> struct is_function<Ret(Args...) &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile &&> : std::true_type {}; // specializations for noexcept versions of all the above (C++17 and later) template<class Ret, class... Args> struct is_function<Ret(Args...) noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile && noexcept> : std::true_type {}; |
[編集] 例
このコードを実行
#include <functional> #include <type_traits> int f(); static_assert(std::is_function_v<decltype(f)>); static_assert(std::is_function_v<int(int)>); static_assert(!std::is_function_v<int>); static_assert(!std::is_function_v<decltype([]{})>); static_assert(!std::is_function_v<std::function<void()>>); struct O { void operator()() {} }; static_assert(std::is_function_v<O()>); struct A { static int foo(); int fun() const&; }; static_assert(!std::is_function_v<A>); static_assert(std::is_function_v<decltype(A::foo)>); static_assert(!std::is_function_v<decltype(&A::fun)>); template<typename> struct PM_traits {}; template<class T, class U> struct PM_traits<U T::*> { using member_type = U; }; int main() { using T = PM_traits<decltype(&A::fun)>::member_type; // T is int() const& static_assert(std::is_function_v<T>); }
[編集] 関連項目
| ある型が与えられた引数型で(std::invokeのように)呼び出し可能であるかをチェックする (クラステンプレート) | |
| (C++11) |
型がオブジェクト型であるかをチェックする (クラステンプレート) |
| (C++11) |
型が共用体でないクラス型であるかをチェックする (クラステンプレート) |