흥미로운 질문입니다. 나는 최근 Andrew Sutton의 Concepts에 대한 이야기를 보았고 Q & A 세션에서 누군가 다음 질문 (다음 링크의 타임 스탬프)을 물었습니다 :
CppCon 2018 : Andrew Sutton
문제가 귀결 그래서 : If I have a concept that says A && B && C, another says C && B && A, would those be equivalent?
앤드류 '예'라고 대답하지만, 컴파일러는 일부 내부 (사용자에게 투명) 방법 (원자 논리적 명제로 개념을 분해 할 수있는 사실을 지적 atomic constraints
그들이 여부 앤드류 용어 말로로) 체크를 동등한.
이제 cppreference가 무엇을 말하는지 살펴보십시오 std::same_as
.
std::same_as<T, U>
서브 섬 std::same_as<U, T>
과 그 반대.
기본적으로 "만약의 경우"관계입니다. 서로를 의미합니다. (논리적 동등성)
필자의 결론은 원자 적 제약이 있다는 std::is_same_v<T, U>
것이다. 방법 컴파일러 치료는 std::is_same_v
그들이 생각하게 할 수 std::is_same_v<T, U>
및 std::is_same_v<U, T>
두 개의 서로 다른 제약 조건으로 (서로 다른 엔티티입니다!). 따라서 std::same_as
그중 하나만 사용하여 구현 하는 경우 :
template< class T, class U >
concept same_as = detail::SameHelper<T, U>;
그런 다음 std::same_as<T, U>
및 std::same_as<U, T>
다른 원자 제약을에 "폭발"과 동일하지 될 것입니다.
글쎄, 왜 컴파일러는 신경 쓰는가?
이 예제를 고려하십시오 .
#include <type_traits>
#include <iostream>
#include <concepts>
template< class T, class U >
concept SameHelper = std::is_same_v<T, U>;
template< class T, class U >
concept my_same_as = SameHelper<T, U>;
// template< class T, class U >
// concept my_same_as = SameHelper<T, U> && SameHelper<U, T>;
template< class T, class U> requires my_same_as<U, T>
void foo(T a, U b) {
std::cout << "Not integral" << std::endl;
}
template< class T, class U> requires (my_same_as<T, U> && std::integral<T>)
void foo(T a, U b) {
std::cout << "Integral" << std::endl;
}
int main() {
foo(1, 2);
return 0;
}
이상적으로는 다음을 my_same_as<T, U> && std::integral<T>
포함합니다 my_same_as<U, T>
. 따라서 컴파일러는 두 번째 템플릿 전문화를 선택해야합니다. 단, 다음과 같은 경우는 예외 error: call of overloaded 'foo(int, int)' is ambiguous
입니다. 컴파일러에서 오류가 발생 합니다.
이 뒤에 그 이유는 이후 있다는 것입니다 my_same_as<U, T>
및 my_same_as<T, U>
서로를 포섭하지 않습니다 my_same_as<T, U> && std::integral<T>
및 my_same_as<U, T>
(포섭의 관계에서 제약 부분적으로 정렬 된 세트) 비교할된다.
그러나 교체하면
template< class T, class U >
concept my_same_as = SameHelper<T, U>;
와
template< class T, class U >
concept my_same_as = SameHelper<T, U> && SameHelper<U, T>;
코드가 컴파일됩니다.
SameHelper<T, U>
의미하지 않는다 사실 일 수도SameHelper<U, T>
수 있습니다.