Open5
C++コンセプト包摂関係練習帖
基礎
template <typename T> concept C1 = true;
template <typename T> concept D1 = false;
namespace Q1 {
template <typename T>
constexpr int f(T) { return 0; }
template <typename T> requires C1<T>
constexpr int f(T) { return 1; }
static_assert(f(42) == 1);
}
namespace Q2 {
template <typename T>
constexpr int f(T) { return 0; }
template <typename T> requires D1<T>
constexpr int f(T) { return 1; }
static_assert(f(42) == 0);
}
namespace Q3 {
template <typename T>
constexpr int f(T) { return 0; }
template <typename T> requires (!C1<T>)
constexpr int f(T) { return 1; }
static_assert(f(42) == 0);
}
namespace Q4 {
template <typename T>
constexpr int f(T) { return 0; }
template <typename T> requires (!D1<T>)
constexpr int f(T) { return 1; }
static_assert(f(42) == 1);
}
Conjunction(&&
)とDisjunction(||
)
template <typename T> concept C1 = true;
template <typename T> concept C2 = true;
template <typename T> concept D1 = false;
template <typename T> concept D2 = false;
namespace Q1 {
template <typename T> requires C1<T>
constexpr int f(T) { return 1; }
template <typename T> requires C1<T> && C2<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == 2);
}
namespace Q2 {
template <typename T> requires C1<T>
constexpr int f(T) { return 1; }
template <typename T> requires C1<T> || C2<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == 1);
}
namespace Q3 {
template <typename T> requires C1<T>
constexpr int f(T) { return 1; }
template <typename T> requires C1<T> && D2<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == 1);
}
namespace Q4 {
template <typename T> requires C1<T>
constexpr int f(T) { return 1; }
template <typename T> requires C1<T> || D2<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == 1);
}
namespace Q5 {
template <typename T> requires D1<T>
constexpr int f(T) { return 1; }
template <typename T> requires D1<T> && C2<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == /*no matching*/);
}
namespace Q6 {
template <typename T> requires D1<T>
constexpr int f(T) { return 1; }
template <typename T> requires D1<T> || C2<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == 2);
}
namespace Q7 {
template <typename T> requires C1<T>
constexpr int f(T) { return 1; }
template <typename T> requires C1<T> && C1<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == /*ambiguous*/);
}
namespace Q8 {
template <typename T> requires C1<T>
constexpr int f(T) { return 1; }
template <typename T> requires C1<T> || C1<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == /*ambiguous*/);
}
制約式(X && Y) || Z
template <typename T> concept C1 = true;
template <typename T> concept C2 = true;
template <typename T> concept C3 = true;
template <typename T> concept D3 = false;
namespace Q1 {
template <typename T> requires (C1<T> && C2<T>) || C3<T>
constexpr int f(T) { return 1; }
template <typename T> requires C3<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == 2);
}
namespace Q2 {
template <typename T> requires (C1<T> && C2<T>) || C3<T>
constexpr int f(T) { return 1; }
template <typename T> requires C1<T> && C2<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == 2);
}
namespace Q3 {
template <typename T> requires (C1<T> && C2<T>) || C3<T>
constexpr int f(T) { return 1; }
template <typename T> requires C1<T> || C3<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == 1);
}
namespace Q4 {
template <typename T> requires (C1<T> && C2<T>) || C3<T>
constexpr int f(T) { return 1; }
template <typename T> requires C1<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == /*ambiguous*/);
}
namespace Q5 {
template <typename T> requires (C1<T> && C2<T>) || D3<T>
constexpr int f(T) { return 1; }
template <typename T> requires D3<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == 1);
}
namespace Q6 {
template <typename T> requires (C1<T> && C2<T>) || D3<T>
constexpr int f(T) { return 1; }
template <typename T> requires C1<T> || D3<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == 1);
}
制約式(X || Y) && Z
template <typename T> concept C1 = true;
template <typename T> concept C2 = true;
template <typename T> concept C3 = true;
namespace Q1 {
template <typename T> requires (C1<T> || C2<T>) && C3<T>
constexpr int f(T) { return 1; }
template <typename T> requires C3<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == 1);
}
namespace Q2 {
template <typename T> requires (C1<T> || C2<T>) && C3<T>
constexpr int f(T) { return 1; }
template <typename T> requires (C1<T> || C2<T>)
constexpr int f(T) { return 2; }
static_assert(f(42) == 1);
}
namespace Q3 {
template <typename T> requires (C1<T> || C2<T>) && C3<T>
constexpr int f(T) { return 1; }
template <typename T> requires C1<T> && C3<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == 2);
}
namespace Q4 {
template <typename T> requires (C1<T> || C2<T>) && C3<T>
constexpr int f(T) { return 1; }
template <typename T> requires C1<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == /*ambiguous*/);
}
namespace Q5 {
template <typename T> requires (D1<T> || C2<T>) && C3<T>
constexpr int f(T) { return 1; }
template <typename T> requires D1<T> || C2<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == 1);
}
namespace Q6 {
template <typename T> requires (D1<T> || C2<T>) && C3<T>
constexpr int f(T) { return 1; }
template <typename T> requires D1<T> && C3<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == 1);
}
否定演算(!
)と原始制約
template <typename T> concept D1 = false;
template <typename T> concept C2 = true;
namespace Q1 {
template <typename T> requires (!D1<T>)
constexpr int f(T) { return 1; }
template <typename T> requires (!D1<T>) && C2<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == /*ambiguous*/);
}
namespace Q2 {
template <typename T> requires (!D1<T>)
constexpr int f(T) { return 1; }
template <typename T> requires (!D1<T>) || C2<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == /*ambiguous*/);
}
template <typename T> concept NotD1 = !D1<T>;
namespace Q3 {
template <typename T> requires NotD1<T>
constexpr int f(T) { return 1; }
template <typename T> requires NotD1<T> && C2<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == 2);
}
namespace Q4 {
template <typename T> requires NotD1<T>
constexpr int f(T) { return 1; }
template <typename T> requires NotD1<T> || C2<T>
constexpr int f(T) { return 2; }
static_assert(f(42) == 1);
}