コンテンツにスキップ

最終更新:2026-10-12

C++ std::function 詳解

最近C++のコードを書いていてis_functionを使う機会があり、ついでにソースコードの実装を見ていたところ、いくつか問題を発見しました。以前私たちが学んだのは3つの点...ですが、6つの点......が何なのかご存知ですか?

同様に、次のようなコードがあった場合:

template<typename... Args>
struct foo(Args......);

これが何を意味するかおわかりでしょうか?

以下、一緒に詳細を深く見ていきましょう!

1.6つの点

6つの点は通常 two ellipsis operators と呼ばれます。6つの点を分割すると、次の3つの場合が得られます

template <typename... Args> void foo1(Args......)
template <typename... Args> void foo2(Args... ...)
template <typename... Args> void foo3(Args..., ...)

これで見やすくなりました。std::is_functionのコードを見てみましょう。

2.is_functionの実装詳細

std::is_functionの実装には、プライマリテンプレートと2つの部分特殊化が関わっています:

// 主模板,假设提供的类型不是函数类型
template<typename T>
struct is_function : std::false_type {};

// 偏特化,用于正常的函数类型
template<typename Ret, typename... Args>
struct is_function<Ret(Args...)> : std::true_type {};

// 偏特化,用于变参函数类型
template<typename Ret, typename... Args>
struct is_function<Ret(Args......)> : std::true_type {};
  • プライマリテンプレートは、与えられた型が関数型ではないと仮定し、std::false_typeを結果として返します。
  • 1番目の部分特殊化は通常の関数型のためのもので、Retは戻り値の型、Args...は引数の型を表します。与えられた型がこの関数シグネチャに一致する場合、std::true_typeが結果となります。
  • 2番目の部分特殊化は可変引数関数型のためのもので、その省略記号は関数が可変個の引数を持つことを表します。同様に、与えられた型がこの関数シグネチャに一致する場合、std::true_typeが結果となります。

3.使用例

最後にstd::is_functionの使用例を示します:

#include <iostream>
#include <type_traits>

int func(int x, int y) { return x + y; }
int vararg_func(int x, ...) { return x; }

int main() {
    std::cout << std::boolalpha;
    std::cout << "Is func a function? " << std::is_function<decltype(func)>::value << std::endl;
    std::cout << "Is vararg_func a function? " << std::is_function<decltype(vararg_func)>::value << std::endl;
    return 0;
}

これが出力されます:

Is func a function? true
Is vararg_func a function? true

理解できましたか、この節は以上です~

関連トピック

コメント