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>
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 ✅