最終更新日時: 2026年07月22日 16時08分23秒 (JST)
rotarymars が更新

履歴 編集

concept
<concepts>

# std::common_reference_with(C++20)

    namespace std {
      template<class T, class U>
      concept common_reference_with =
        same_as<common_reference_t<T, U>, common_reference_t<U, T>> &&
        convertible_to<T, common_reference_t<T, U>> &&
        convertible_to<U, common_reference_t<T, U>>;
    }

## 概要

`common_reference_with`は、`T, U`の間で、どちらの型からも変換可能な共通の参照型が存在することを表すコンセプトである。

2つの型`T, U`は以下の全ての条件を満たす場合にのみ、共通の参照型を持つ。

- `C = common_reference_t<T, U>`が有効な型である
- 型`T, C`は、`convertible_to<T, C>`のモデルである
- 型`U, C`は、`convertible_to<U, C>`のモデルである

このような型`C`は、必ずしも`T`や`U`と同じ型である必要はなく、参照型でなくても良い。

## モデル

`C = common_reference_t<T, U>`、等しさを保持し`decltype((t1))`と`decltype((t2))`が共に`T`となるような式`t1, t2`及び、等しさを保持し`decltype((u1))`と`decltype((u2))`が共に`U`となるような式`u1, u2`について以下の条件を満たす場合に限って、型`T, U`は`common_reference_with`のモデルである。

- `t1`と`t2`が等値である場合にのみ、`C(t1)`と`C(t2)`も等値となる
- `u1`と`u2`が等値である場合にのみ、`C(u1)`と`C(u2)`も等値となる

## 備考

このコンセプトをカスタマイズするには、`basic_common_reference`を利用する。

## 例

    #include <iostream>
    #include <concepts>
    #include <vector>
    #include <string>
    #include <string_view>
    #include <utility>

    template<typename T, typename U>
    requires std::common_reference_with<T, U>
    void f() {
      std::cout << "T, U share a common reference type" << std::endl;
    }

    template<typename T, typename U>
    void f() {
      std::cout << "T, U not share a common reference type" << std::endl;
    }

    int main()
    {
      f<std::size_t&, int&>();
      f<std::string&, std::string_view&>();
      f<std::vector<int>, std::vector<int>&>();
      f<std::vector<int>, std::vector<double>>();
      f<std::pair<int&, double&>, std::pair<int, double>>();
    }

### 出力

    T, U share a common reference type
    T, U share a common reference type
    T, U share a common reference type
    T, U not share a common reference type
    T, U share a common reference type

## バージョン

### 言語

- C++20

### 処理系

- Clang: ??
- GCC: 10.1 ✅
- Visual C++: 2019 Update 3 ✅

## 関連項目

- C++20 コンセプト
- `common_reference`
- `basic_common_reference`

## 参照

- P0898R3 Standard Library Concepts
- P1754R1 Rename concepts to standard_case for C++20, while we still can
- LWG Issue 3154. `Common` and `CommonReference` have a common defect