最終更新日時: 2025年06月30日 14時31分11秒 (JST)
Raclamusi が更新

履歴 編集

type-alias
<type_traits>

# std::void_t(C++17)

    namespace std {
      template <class...>
      using void_t = void;
    }

## 概要

0個以上の任意の型をvoidに変換する。

## 効果

与えられた型の中に一つでもill-formedとなる型があれば`void_t`もまたill-formedとなる。そうでなければ（与えられた型がすべてwell-formedならば）`void_t`は`void`となる。

すなわち、与えられた型を一つづつ評価していった結果エラーとなる型が現れた場合に`void_t`もまたエラーとなる。

`void_t`はSFINAEと組み合わせて型が持つ特性・メンバや適用可能な操作を検出するのに使用される。そのような手法はdetection idiomと呼ばれる。

## 備考

C++14まではエイリアステンプレートでの未使用のテンプレートパラメータの評価に関しての規定が無かったことから、以下のような少し複雑な実装になっている場合がある。 この問題はcore issue 1558で把握され、C++17にて修正された。

    template <class... Types>
    struct Tester {
      using type = void;
    };

    template <class... Types>
    using void_t = typename Tester<Types...>::type;

## 例

    #include <iostream>
    #include <type_traits>
    #include <vector>

    template<class, template<class> class, class = std::void_t<>>
    struct detect : std::false_type {};

    template<class T, template<class> class Check>
    struct detect<T, Check, std::void_t<Check<T>>>
      : std::true_type {};

    template<class T>
    using has_iterator_type_impl = typename T::iterator;

    template<class T>
    using has_iterator_type = detect<T, has_iterator_type_impl>;

    template<class T>
    using is_equality_comparable_impl = decltype(std::declval<const T&>() == std::declval<const T&>());

    template<class T>
    using is_equality_comparable = detect<T, is_equality_comparable_impl>;

    struct NonComparable {};

    int main()
    {
      std::cout << std::boolalpha;

      //::iteratorを持っているかの検出
      std::cout << has_iterator_type<int>::value << std::endl;
      std::cout << has_iterator_type<std::vector<int>>::value << std::endl;

      //等値比較可能かの検出
      std::cout << is_equality_comparable<int>::value << std::endl;
      std::cout << is_equality_comparable<NonComparable>::value << std::endl;
    }

### 出力

    false
    true
    true
    false

## バージョン

### 言語

- C++17

### 処理系

- Clang: 3.6 ✅
- GCC: 6.3 ✅
- Visual C++: 2015 ✅, 2017 ✅
  - 2015では備考にある複雑な実装になっている。

## 参照

- C++1z void_t - Faith and Brave - C++で遊ぼう
- Detection Idiom - yohhoyの日記
- Proposing Standard Library Support for the C++ Detection Idiom, v2
- core issue 1558