콘셉트 (C++)
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
콘셉트는 C++ 템플릿 프로그래밍에서 형식 검사를 도입하고, 컴파일러 진단을 개선하며, 함수 오버로드 및 특수화를 선택하는 데 사용되는 기능이다. C++20 표준에 도입되었으며, 템플릿 인수가 특정 기능을 제공하는지 확인하여 템플릿의 유효성을 검사한다. 초기에는 "C++0x 콘셉트"라는 형태로 C++11에 포함될 예정이었으나 삭제되었고, C++20에서는 "콘셉트 라이트"라는 이름으로 채택되었다. 콘셉트는 템플릿 타입 검사, 컴파일러 진단 개선, 함수 오버로드 및 특수화 선택, 타입 추론 제한 등에 사용되며, 제약 조건은 타입 제약, requires-절, 제약된 자리 표시자 타입, 후행 requires-절 등 다양한 위치에 적용될 수 있다.
더 읽어볼만한 페이지
- C++ - 헤더 파일
헤더 파일은 프로그래밍 언어에서 코드 재사용성, 모듈화, 컴파일 시간 단축에 기여하며 함수 프로토타입, 변수 선언 등을 포함하고 `#include` 지시어로 소스 코드에 포함되어 사용되는 파일이다. - C++ - 소멸자 (컴퓨터 프로그래밍)
소멸자는 객체가 메모리에서 제거되기 직전에 호출되는 멤버 함수로, 객체 자원 해제 및 정리 작업을 수행하며, C++ 등 여러 언어에서 구현되고 메모리 누수 방지에 기여한다.
| 콘셉트 (C++) |
|---|
2. 역사
콘셉트의 다른 형태인 "C++0x 콘셉트"가 C++11에 잠깐 승인됐었으나 2009년에 삭제되었다.[24] "C++0x 콘셉트"는 추가적으로 콘셉트 맵(예를 들어 "Stack" 콘셉트가 'push()'라는 연산을 요구할 때, `std::vector`의 `push_back()`과 같은 연산을 'push()'와 매핑시킬 수 있음)과 ''axiom''(연관성, 교환 가능성과 같은 의미론적 속성을 명기하여 컴파일러가 이용할 수 있게 함)이 포함돼 있었다.
이 버려진 신청과 대비하여, C++20의 콘셉트는 "콘셉트 라이트"(Concepts Lite)[25]라고 불리기도 한다.
2016년 3월 C++ 표준 위원회 회의에서 진화 작업 그룹은 개념을 주류 C++17 표준에 병합하기로 결정했지만, 전체 위원회에서 이 안건은 부결되었다.[9]
개념 v1은 C++20 초안에 병합되었다.[10]
개념에 의존하는 Range 기능의 "The One Range" 버전도 C++20에 병합되었다.
2. 1. C++11 이전
C++11 표준화 과정에서 "C++0x 개념"이라는 이름으로 개념의 또 다른 형태가 제안되었으나, 2009년에 삭제되었다.[7] "C++0x 개념"에는 개념 자체 외에도 ''개념 맵'' 및 ''공리'' 기능이 포함되었다. 개념 맵은 "Stack" 개념이 를 수용하도록 하여, "Stack" 연산을 의 연산에 자동으로 매핑하는 기능이다. 공리는 결합성 또는 교환성과 같은 의미적 속성을 지정하여 컴파일러가 증명 없이 이러한 속성을 활용할 수 있도록 하는 기능이다.이 폐기된 제안은 C++20 버전의 개념과 비교하여 "개념 라이트"라고 불리기도 한다.[8] 2016년 3월 C++ 표준 위원회 회의에서 개념을 주류 C++17 표준에 병합하기로 결정했지만, 전체 위원회에서 부결되었다.[9] 개념 v1은 C++20 초안에 병합되었다.[10]
2. 2. C++20 채택
콘셉트의 다른 형태인 "C++0x 콘셉트"가 C++11에 잠깐 승인됐었으나 2009년에 삭제되었다.[24] "C++0x 콘셉트"는 콘셉트 맵과 ''axiom''이 포함돼 있었다.이 버려진 신청과 대비하여, C++20의 콘셉트는 "콘셉트 라이트"(Concepts Lite)라고 불리기도 한다.[25]
2016년 3월 C++ 표준 위원회 회의에서 진화 작업 그룹은 개념을 주류 C++17 표준에 병합하기로 결정했지만, 전체 위원회에서 이 안건은 부결되었다.[9]
개념 v1은 C++20 초안에 병합되었다.[10]
개념에 의존하는 Range 기능의 "The One Range" 버전도 C++20에 병합되었다.
2. 3. C++0x 콘셉트 (삭제됨)
"C++0x 콘셉트"는 C++11에 포함될 예정이었으나 2009년에 삭제된 콘셉트의 다른 형태이다.[24][7] "C++0x 콘셉트"는 콘셉트 맵과 공리(axiom)를 포함하고 있었다. 콘셉트 맵은 "Stack" 콘셉트가 'push()' 연산을 요구할 때, `std::vector`의 `push_back()`과 같은 연산을 'push()'와 매핑시키는 기능을 제공한다. 공리는 연관성, 교환 가능성과 같은 의미론적 속성을 명기하여 컴파일러가 이용할 수 있도록 한다.C++20 콘셉트는 "콘셉트 라이트"(Concepts Lite)라고도 불리며,[25][8] C++0x 콘셉트와는 다르게 콘셉트 맵과 공리 기능은 포함되지 않았다. 2016년 3월 C++ 표준 위원회 회의에서 콘셉트를 C++17 표준에 병합하려는 결정이 있었지만, 전체 위원회에서 부결되었다.[9] 콘셉트 v1은 C++20 초안에 병합되었다.[10]
3. 주요 사용법
개념의 주요 사용법은 다음과 같다:
- 템플릿 프로그래밍에 형식 검사를 도입한다.[12]
- 실패한 템플릿 인스턴스화에 대한 단순화된 컴파일러 진단을 제공한다.[12]
- 형식 속성을 기반으로 함수 템플릿 오버로드 및 클래스 템플릿 특수화 선택을 가능하게 한다.[12]
- 자동 형식 추론을 제한한다.[12]
개념은 이름을 가진 구조이며, 형식이 제공해야 하는 기능을 지정한다. 이는 객체 지향 프로그래밍에서 형식의 역할 제한을 기본 클래스를 사용하여 정의하는 것과 유사하다. 하지만 객체 지향 프로그래밍과는 달리 개념의 정의 자체에는 템플릿에 전달되는 형식이 명시적으로 연결되지 않으며, 템플릿 정의 측에서 연결된다.
```cpp
template
const T& min(const T &x, const T &y)
{
return x < y ? x : y;
}
```
위 코드에서 템플릿 형식 인수에 ''class''나 ''typename''을 사용하여 임의의 형식으로 지정하는 대신, 미리 정의된 개념인 ''LessThanComparable''을 사용하고 있다. 템플릿 함수 ''min''에 전달된 형식이 개념 ''LessThanComparable''을 충족하지 못하는 경우, 컴파일 오류가 발생하며, 템플릿 인스턴스화에 사용된 형식이 ''LessThanComparable'' 개념에 적합하지 않았다는 오류가 보고된다.
더 일반적인 개념 사용 표기법은 다음과 같다.
```cpp
template
const T& min(const T &x, const T &y)
{
return x < y ? x : y;
}
```
''requires'' 키워드 뒤에는 개념 선언 목록이 이어진다. 이를 통해 여러 형식을 사용하는 개념을 사용할 수 있다. 또한, ''requires !LessThanComparable
개념은 다음과 같이 정의된다.
```cpp
auto concept LessThanComparable
{
bool operator<(T, T);
}
```
이 예제에 포함된 키워드 ''auto''는 개념에 기술된 연산을 제공하는 모든 형식이 개념을 충족한다는 것을 나타낸다. ''auto'' 키워드가 없는 경우, 개념을 충족하는 형식을 선언하기 위해 개념 맵을 사용해야 한다.
이 개념은 "자신과 같은 형식의 인수를 두 개 받아 bool을 반환하는 연산자
< 를 가진 모든 형식은 ''LessThanComparable''이다"라는 것을 나타낸다. 연산자는 전역 함수가 아닌 형식 T의 멤버 함수여야 한다.개념은 여러 형식을 포함할 수도 있다. 예를 들어, 두 개의 형식을 받아, 한쪽이 다른 쪽으로 변환될 수 있다는 것을 나타내는 개념은 다음과 같다.
```cpp
auto concept Convertible
{
operator U(const T&);
}
```
이를 템플릿에서 사용하려면 개념의 일반적인 사용 표기법을 사용해야 한다.
```cpp
template
U convert(const T& t)
{
return t;
}
```
개념은 합성될 수 있다. 예를 들어, ''Regular''라는 개념이 주어졌을 경우:
```cpp
concept InputIterator
{
require Regular
Value operator*(const Iter&);
Iter& operator++(Iter&);
Iter operator++(Iter&, int);
}
```
''InputIterator'' 개념에 전달된 템플릿 인수 중 첫 번째는 ''Regular'' 개념을 충족하는지 확인된다.
상속을 수행하듯이 개념도 다른 개념에서 파생될 수 있다. 그리고 클래스 상속처럼, 파생 개념도 기본 개념의 요구 사항을 충족한다. 파생 개념은 클래스 파생처럼 정의된다.
```cpp
concept ForwardIterator
{
// 여기에 다른 요구 사항을 추가한다.
}
```
개념에 형식 이름(typename)을 연결할 수도 있다. 이를 통해 형식 이름을 사용할 수 있음을 개념의 요구 사항으로 표현할 수 있다.
```cpp
concept InputIterator
{
typename value_type;
typename reference;
typename pointer;
typename difference_type;
require Regular
require Convertible[13]
```
구체적으로 다음과 같은 사용법이 있다.
; 템플릿 타입 검사
: 템플릿 프로그래밍에 형식 검사를 도입한다.
; 컴파일러 진단 개선
: 프로그래머가 템플릿의 요구 사항을 충족하지 않는 템플릿 인수를 사용하려고 하면 컴파일러는 오류를 발생시킨다. 콘셉트가 없는 경우, 이러한 오류는 호출 컨텍스트가 아닌, 타입이 사용된 내부적이고 종종 깊이 중첩된 구현 컨텍스트에서 보고되기 때문에 이해하기 어렵다.
: 예를 들어, `std::sort`는 첫 번째 두 인수가 임의 접근 반복자여야 한다. 인수가 반복자가 아니거나 다른 범주의 반복자인 경우, `std::sort`가 매개변수를 양방향 반복자로 사용하려고 시도할 때 오류가 발생한다.
```cpp
// std::list는 일반적으로 이중 연결 목록이며, 해당 반복자는 임의 접근을 지원하지 않습니다.
std::list
std::sort(l.begin(), l.end());
```
: 콘셉트가 없는 일반적인 컴파일러 진단은 두 반복자를 빼는 식을 컴파일하지 못하는 것으로 시작하여 50줄이 넘는 출력을 생성한다.
```
'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = std::_List_iterator
error: 'operator-'에 대한 일치하는 항목이 없습니다(피연산자 유형은 'std::_List_iterator
std::__lg(__last - __first) * 2,
[..]
```
: 콘셉트가 사용되면 오류를 감지하여 호출 컨텍스트에서 보고할 수 있다.
```cpp
error: 'void std::sort(_RAIter, _RAIter) [with _RAIter = std::_List_iterator
note: 컨셉 'RandomAccessIterator()'가 충족되지 않았습니다.
```
; 함수 오버로드 및 특수화 선택
: 콘셉트는 템플릿 인자의 속성을 기반으로 템플릿 함수 오버로드나 클래스 템플릿 특수화를 선택하는 데 SFINAE와 tag dispatching 대신 사용될 수 있다. 만약 인자가 둘 이상의 콘셉트를 만족시키는 경우, 좀 더 제약이 많은 콘셉트와 연관된 오버로드가 선택된다.
; 타입 추론 제한
: 변수 선언과 함수 반환 타입을 정할 때, 콘셉트를 사용하여 무제한 타입 추론을 하는 `auto`를 대체할 수 있다.
```cpp
auto x1 = f(y); //x1의 타입은 f의 리턴값에 의해 추론됨
Sortable x2 = f(y); // x2의 타입도 추론되나, Sortable을 만족하는 경우에만 컴파일됨
```
: `auto` 대신 콘셉트를 사용하면, `x2`의 타입은 `Sortable`을 만족하는 경우에만 컴파일된다.
3. 1. 템플릿 타입 검사
템플릿 프로그래밍에 형식 검사를 도입한다.3. 2. 컴파일러 진단 개선
프로그래머가 템플릿의 요구 사항을 충족하지 않는 템플릿 인수를 사용하려고 하면 컴파일러는 오류를 발생시킨다. 콘셉트가 없는 경우, 이러한 오류는 호출 컨텍스트가 아닌, 타입이 사용된 내부적이고 종종 깊이 중첩된 구현 컨텍스트에서 보고되기 때문에 이해하기 어렵다.예를 들어, `std::sort`는 첫 번째 두 인수가 임의 접근 반복자여야 한다. 인수가 반복자가 아니거나 다른 범주의 반복자인 경우, `std::sort`가 매개변수를 양방향 반복자로 사용하려고 시도할 때 오류가 발생한다.
```cpp
// std::list는 일반적으로 이중 연결 목록이며, 해당 반복자는 임의 접근을 지원하지 않습니다.
std::list
std::sort(l.begin(), l.end());
```
콘셉트가 없는 일반적인 컴파일러 진단은 두 반복자를 빼는 식을 컴파일하지 못하는 것으로 시작하여 50줄이 넘는 출력을 생성한다.
```
'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = std::_List_iterator
error: 'operator-'에 대한 일치하는 항목이 없습니다(피연산자 유형은 'std::_List_iterator
std::__lg(__last - __first) * 2,
[..]
```
콘셉트가 사용되면 오류를 감지하여 호출 컨텍스트에서 보고할 수 있다.
```cpp
error: 'void std::sort(_RAIter, _RAIter) [with _RAIter = std::_List_iterator
note: 컨셉 'RandomAccessIterator()'가 충족되지 않았습니다.
3. 3. 함수 오버로드 및 특수화 선택
콘셉트는 템플릿 인자의 속성을 기반으로 템플릿 함수 오버로드나 클래스 템플릿 특수화를 선택하는 데 SFINAE와 tag dispatching 대신 사용될 수 있다. 만약 인자가 둘 이상의 콘셉트를 만족시키는 경우, 좀 더 제약이 많은 콘셉트와 연관된 오버로드가 선택된다.3. 4. 타입 추론 제한
변수 선언과 함수 반환 타입을 정할 때, 콘셉트를 사용하여 무제한 타입 추론을 하는 `auto`를 대체할 수 있다.```cpp
auto x1 = f(y); //x1의 타입은 f의 리턴값에 의해 추론됨
Sortable x2 = f(y); // x2의 타입도 추론되나, Sortable을 만족하는 경우에만 컴파일됨
```
`auto` 대신 콘셉트를 사용하면, `x2`의 타입은 `Sortable`을 만족하는 경우에만 컴파일된다.
4. 제약 조건의 종류 및 사용 위치
함수 템플릿 시그니처에는 제약 조건을 사용할 수 있는 다섯 가지 다른 위치가 있다 (아래에 C1에서 C5로 표시).[1]
```cpp
template
requires C2
C3 auto Fun(C4 auto param) requires C5
```
제약 조건 형태 `C1` 및 `C2`는 모든 종류의 템플릿에서 사용할 수 있다.
4. 1. 타입 제약 (C1)
함수 템플릿 시그니처에는 제약 조건을 사용할 수 있는 다섯 가지 다른 위치가 있다(아래에 C1에서 C5로 표시).[1]
```cpp
template
requires C2
C3 auto Fun(C4 auto param) requires C5
```
제약 조건 형태 `C1` 및 `C2`는 모든 종류의 템플릿에서 사용할 수 있다.
4. 2. requires-절 (C2)
함수 템플릿 시그니처에는 제약 조건을 사용할 수 있는 다섯 가지 다른 위치가 있다(아래에 C1에서 C5로 표시).[1]
```cpp
template
requires C2
C3 auto Fun(C4 auto param) requires C5
```
제약 조건 형태 `C1` 및 `C2`는 모든 종류의 템플릿에서 사용할 수 있다.
4. 3. 제약된 자리 표시자 타입 (C3, C4)
`auto` 변수와 같은 자리 표시자 변수에 대해 동일한 구문을 사용하여 제약을 적용할 수 있다.[1] C++20은 매개변수 선언에서 `auto`를 자리 표시자 타입으로 사용하는 약식 함수 템플릿을 추가했으며,[2] 제약된 자리 표시자 타입을 사용하면 함수의 자동 추론 반환 타입 또는 변수에 제약을 적용할 수 있다.
```cpp
auto x1 = f(y); // x1의 형식은 f가 반환하는 것으로 추론됩니다.
Sortable auto x2 = f(y); // x2의 형식은 추론되지만 Sortable을 만족하는 경우에만 컴파일됩니다.
4. 4. 후행 requires-절 (C5)
함수 템플릿 시그니처에는 제약 조건을 사용할 수 있는 다섯 가지 다른 위치가 있다(아래에 C1에서 C5로 표시됨).[1]
```cpp
template
requires C2
C3 auto Fun(C4 auto param) requires C5
```
제약 조건 형태 `C1` 및 `C2`는 모든 종류의 템플릿에서 사용할 수 있다.
5. 예제: equality_comparable
다음은 C++20 표준 라이브러리의 `<concepts>` 헤더에 정의된 "equality_comparable" 콘셉트의 선언이다. 이 콘셉트는 타입 `T`에 대해 lvalue `a`와 `b`가 타입 `T`일 때, `a==b` 및 `a!=b` 표현식과 역순인 `b==a` 및 `b!=b`가 컴파일되고, 그 결과가 "boolean-testable" 콘셉트를 만족하는 타입으로 변환될 수 있는 경우 충족된다.
```cpp
// 다음 콘셉트는 equality_comparable을 빌드하는 데 사용되는 구현 세부 정보입니다.
template
concept weakly_equality_comparable_with = requires(const remove_reference
{ a == b } -> std::same_as
{ a != b } -> std::same_as
{ b == a } -> std::same_as
{ b != a } -> std::same_as
};
template
concept equality_comparable = weakly_equality_comparable_with
```
이 콘셉트에 제약된 함수 템플릿은 다음과 같이 선언할 수 있다.
```cpp
void f(const equality_comparable auto&); // 제약된 자리 표시자 타입을 사용한 제약된 축약형 함수 템플릿 선언 (위의 C4)
```
또는
```cpp
template
void f(const T&); // 타입 제약을 사용한 제약된 함수 템플릿 선언 (위의 C1)
```
그리고 다음과 같이 호출할 수 있다.
```cpp
f(42); // OK, int는 equality_comparable을 만족합니다
6. 구현 현황
콘셉트는 GCC 6에서 ISO/IEC TS 19217:2015에 명시된 대로 구현되었다.[21] C++17에 포함시키려는 시도가 있었으나 실패했다.[22] 이후 콘셉트 v1은 C++20 초안에 포함되었다.[23] C++20 콘셉트는 GCC 10,[4] MSVC 19.30,[5] Clang 10에서 완전히 구현되었다.[6]
7. 관련 기능 (C++0x, 삭제됨)
개념을 기반으로 한 기능, 그리고 개념의 라이브러리도 도입될 예정이었다. 개념 삭제 후에는 개념을 사용하지 않도록 수정되었다. 수정 후 내용은 C++0x을 참조하십시오.
; 범위 기반 for 루프
C++11에 채택된 범위 기반 `for` 루프는 Boost C++ 라이브러리의 "범위" 개념을 활용한다. 범위는 컨테이너와 유사하게 리스트의 두 지점을 통해 리스트를 표현한다. 정렬된 컨테이너는 범위 개념의 상위에 있으며, 두 개의 이터레이터를 통해 범위를 정의할 수 있다.
범위 기반 `for` 루프는 이러한 범위 개념을 이용하여 간단한 반복을 수행한다.
```cpp
int my_array[5] = { 1, 2, 3, 4, 5 };
for (int &x : my_array) {
x *= 2;
}
```
위 코드에서 `for` 루프의 첫 번째 부분은 범위를 반복하기 위해 사용하는 변수 `x`를 정의하며, 이 변수는 루프 범위 내에서만 유효하다. 콜론(:) 뒤의 두 번째 부분은 반복 대상 범위를 지정한다. C 스타일 배열은 범위 개념으로 변환 가능하므로 위와 같이 사용 가능하다. `std::vector` 등 범위 개념을 만족하는 모든 것에 적용할 수 있다.
; 콘셉트 라이브러리
C++0x에는 콘셉트 라이브러리가 추가될 예정이었다.[16]
- `<concepts>`: `<type_traits>`의 콘셉트 버전으로, HasPlus(+ 연산자를 사용할 수 있다), DefaultConstructible(디폴트 생성자를 통한 생성이 가능하다) 등 기본적인 성질을 나타내는 콘셉트가 모여 있다.[16]
- `<container_concepts>`: STL 컨테이너를 규정하는 콘셉트.[17]
- `<iterator_concepts>`: 반복자를 규정하는 콘셉트.[18]
- `<memory_concepts>`: 할당자를 규정하는 콘셉트.[19]
7. 1. 범위 기반 for 루프
C++11에 채택된 범위 기반 `for` 루프는 Boost C++ 라이브러리의 "범위" 개념을 활용한다. 범위는 컨테이너와 유사하게 리스트의 두 지점을 통해 리스트를 표현한다. 정렬된 컨테이너는 범위 개념의 상위에 있으며, 두 개의 이터레이터를 통해 범위를 정의할 수 있다.범위 기반 `for` 루프는 이러한 범위 개념을 이용하여 간단한 반복을 수행한다.
```cpp
int my_array[5] = { 1, 2, 3, 4, 5 };
for (int &x : my_array) {
x *= 2;
}
```
위 코드에서 `for` 루프의 첫 번째 부분은 범위를 반복하기 위해 사용하는 변수 `x`를 정의하며, 이 변수는 루프 범위 내에서만 유효하다. 콜론(:) 뒤의 두 번째 부분은 반복 대상 범위를 지정한다. C 스타일 배열은 범위 개념으로 변환 가능하므로 위와 같이 사용 가능하다. `std::vector` 등 범위 개념을 만족하는 모든 것에 적용할 수 있다.
7. 2. 콘셉트 라이브러리
C++0x에는 콘셉트 라이브러리가 추가될 예정이었다.[16]참조
[1]
서적
Programming with C++20
https://andreasferti[...]
Fertig Publications
2021
[2]
웹사이트
ISO/IEC 14882:2020
http://www.iso.org/i[...]
ISO
2022-07-14
[3]
웹사이트
GCC 6 Release Series - Changes, New Features, and Fixes
https://gcc.gnu.org/[...]
[4]
웹사이트
C++ compiler support (gcc)
https://gcc.gnu.org/[...]
[5]
웹사이트
C++ compiler support
https://en.cpprefere[...]
[6]
웹사이트
C++ Support in Clang
https://clang.llvm.o[...]
[7]
웹사이트
The C++0x "Remove Concepts" Decision
http://www.drdobbs.c[...]
Dr. Dobbs
2009-07-22
[8]
웹사이트
Concepts Lite: Constraining Templates with Predicates
https://isocpp.org/b[...]
isocpp.org
2013-02-24
[9]
웹사이트
Why Concepts didn't make C++17
http://honermann.net[...]
honermann.net
2016-04-19
[10]
웹사이트
2017 Toronto ISO C++ Committee Discussion Thread (Concepts in C++20; Coroutines, Ranges and Networking TSes published) : cpp
https://www.reddit.c[...]
2017-07-15
[11]
간행물
The Removal of Concepts From C++0x
http://www.informit.[...]
InformIT
2009-07-23
[12]
문서
Pete Becker, Working Draft, Standard for Programming Language C++, 2009-06-22 コンセプトは14.10節
http://www.open-std.[...]
[13]
문서
N2914 14.10.1.4 Axioms
[14]
문서
N2914 6.9 Late-checked block
[15]
문서
N2914 14.10.4 Supported concepts
[16]
문서
N2914 20.2 Concepts
[17]
문서
N2914 23.2.6 Container concepts
[18]
문서
N2914 24.2 Iterator concepts
[19]
문서
N2914 20.8 Memory
[20]
웹인용
ISO/IEC TS 19217:2015
http://www.iso.org/i[...]
ISO
2015-11-15
[21]
웹인용
GCC 6 Release Series - Changes, New Features, and Fixes
https://gcc.gnu.org/[...]
[22]
웹인용
Why Concepts didn’t make C++17
http://honermann.net[...]
honermann.net
2018-10-11
[23]
웹인용
2017 Toronto ISO C++ Committee Discussion Thread (Concepts in C++20; Coroutines, Ranges and Networking TSes published) : cpp
https://www.reddit.c[...]
[24]
웹인용
The C++0x "Remove Concepts" Decision
http://www.drdobbs.c[...]
Dr. Dobbs
2018-10-11
[25]
웹인용
Concepts Lite: Constraining Templates with Predicates
https://isocpp.org/b[...]
isocpp.org
2013-02-24
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com