가변적 인 템플릿을 광범위하게 사용하는 C++ 11의 대규모 소프트웨어 인프라에서 작업하고 있습니다. 내 질문은 다음과 같습니다 :이 접근법의 확장 성은 무엇입니까? 첫째, 가변 템플릿이 취할 수있는 인수의 수에는 상한이 있습니까? 둘째, 많은 인수가 사용되는 경우 (그리고 확장으로 인해 템플릿 화 된 메소드의 여러 구현에 따라 달라지는 이러한 인수의 많은 조합) 최첨단 컴파일러의 주요 문제는 코드 팽창입니다.variadic 템플릿의 확장 성
답변
필자는 특정 컴파일러 (g ++ 4.8.1 Linux)의 템플릿 매개 변수 수에 제한이 있는지를 알아 냈습니다. 다음 테스트 케이스를 사용했습니다 :
template <int I>
struct this_is_a_ridiculously_long_struct_name_youd_never_use_in_real_life {};
template <int Depth, typename... T>
struct A
{
using e = this_is_a_ridiculously_long_struct_name_youd_never_use_in_real_life<Depth>;
A() {};
A<Depth - 1, e, e, e, e, e, e, e, e, e, e, e, e, e, e, e, e, e, e, e, e, T...> a;
};
template <typename... T>
struct A<0, T...>
{
};
int main()
{
A<899> a;
}
템플릿 반복 깊이의 기본값은 g ++에서 900이므로 사용자가 보는 899 매개 변수입니다. 엄청나게 긴 구조체 이름은 링커가 처리하기에는 너무 큰 심볼을 생성 할 수 있는지 여부를 확인하는 데 사용됩니다.
테스트 케이스에서 무슨 일이 벌어지는 지 알 수없는 경우 기본적으로 A
의 모든 인스턴스화는 20 개의 추가 템플릿 매개 변수를 추가하는 멤버 변수를 만듭니다. 부분 전문화는 재귀를 중지하는 데 사용됩니다. 결국, A<0, ...>
은 18000 개의 템플릿 매개 변수 영역에 있습니다.
내가 발견 한 것은 g ++가 이것을 잘 처리했다는 것입니다. 그것에 대해 생각하는 데는 꽤 시간이 걸렸지 만 상당한 메모리를 사용했지만 단순히 템플릿 매개 변수의 수를 늘려서 실패 할 수는 없었습니다. Clang 3.1은 또한 템플릿 재귀 깊이가 충분히 설정되면 (900) 아무런 문제없이 이것을 처리했습니다.
또한, 맹 글링 된 심볼 이름이 실제로 커지더라도 nm
또는 ld
중 하나를 사용하지 못했습니다. (Linux/Itanium mangling scheme은 대체를 사용하므로 동일한 유형의 반복 된 템플릿 매개 변수가 전체 유형 이름을 반복하지 않고 S0
, S1
등으로 표시됩니다.) 빠른 google은 전환하지 않는 것 같습니다 ELF 심볼 길이에 제한을 두지 만, 아마도 다른 누군가는 그러한 한계가 존재 하는지를 안다.
결론적으로 Linux의 g ++ 및 clang의 경우 적어도 템플릿 매개 변수의 수에 대한 실질적인 제한은없는 것 같습니다.
질문의 두 번째 부분에 대해서는 코드가 부풀어 오르는 것과 관련하여 컴파일러 최적화가 관련되면 특히 그렇다고 말하기가 어렵습니다. variadic 템플릿을 사용하면 재귀를 쉽게 수행 할 수 있지만 컴파일러는 중간 유형을 쉽게 제거 할 수 있습니다. 나는 단지 그것을 시도하고 볼 것을 제안 할 수있다.
내가 사용하고있는 템플릿 인수의 수 (생성 된 코드에서)는 고객에 따라 다르므로 제한이 없습니다. 따라서 내 대답 boost :: mpl이 제한을 피하기 위해 사용하는 것이 좋습니다. –
- 1. variadic 템플릿의 성능 영향
- 2. Variadic 템플릿의 개별 유형 액세스
- 3. Variadic 템플릿 람다 확장
- 4. 지연 성 소켓 - 확장 성?
- 5. 하나의 variadic 클래스 템플릿의 중첩 된 variadic 클래스 템플릿의 변형 만 허용하도록 variadic 함수 템플릿을 제한 하시겠습니까?
- 6. Variadic 템플릿의 정적 정적 배열 C++
- 7. 웹 API 병행 성 및 확장 성
- 8. Oracle Forms의 확장 성
- 9. Ext4의 확장 성
- 10. Tomcat 확장 성 ejb
- 11. JSON의 확장 성
- 12. GPU의 확장 성 분석
- 13. Azure에서 MySQL의 확장 성
- 14. NHibernate QueryOver 확장 성
- 15. 이벤트 처리기와 확장 성
- 16. 오픈 소스없는 확장 성
- 17. IIS 확장 성
- 18. 확장 성 Boost.Asio
- 19. Java의 확장 성
- 20. JGit 확장 성 제한
- 21. ASP.NET의 모노 확장 성
- 22. 확장 성 테스트 도구
- 23. Mochiweb의 확장 성 기능
- 24. 사라진 확장 성
- 25. Outlook의 VBA 확장 성
- 26. Visual Studio 확장 성
- 27. aho corasick의 확장 성
- 28. 개선 SQL 확장 성
- 29. 확장 성 처리 세션
- 30. 태그도 시스템 확장 성
이론적으로 제한이 없지만 실제로는 RAM과 같은 일부 제한된 리소스에 의해 결정되는 약간의 제한이 있습니다. 한도에 이르면 더 큰 문제가 생길 수 있으므로 걱정하지 않으셔도됩니다. –
두 번째 질문은 정확히 몇 개의 템플릿 인수가 있는지보다는 나머지 코드에 더 의존하기 때문에 대답하기가 어렵습니다. stuff compile time을 계산하기 위해 많은 템플릿 인자를 사용한다면, 어떤 코드도 생성되지 않을 수도 있습니다. 그렇지 않으면 코드가 생성되는 경우 인스턴스화 수는 곱셈 요소가됩니다. 이것은 비 변형 템플릿과 다르지 않습니다. –
C++ 11 Standard의 Annex B (Implementation 수량)는 * variadic * 템플릿에 대해서는 특별히 언급하지 않았지만 적어도 256 개의 함수 매개 변수와 1024 개의 템플릿 매개 변수를 권장합니다. 그러나 맹 글링 된 이름이 너무 길어질수록 문제가 생길 수 있습니다. – Oberon