2013-09-27 4 views
18

가변적 인 템플릿을 광범위하게 사용하는 C++ 11의 대규모 소프트웨어 인프라에서 작업하고 있습니다. 내 질문은 다음과 같습니다 :이 접근법의 확장 성은 무엇입니까? 첫째, 가변 템플릿이 취할 수있는 인수의 수에는 상한이 있습니까? 둘째, 많은 인수가 사용되는 경우 (그리고 확장으로 인해 템플릿 화 된 메소드의 여러 구현에 따라 달라지는 이러한 인수의 많은 조합) 최첨단 컴파일러의 주요 문제는 코드 팽창입니다.variadic 템플릿의 확장 성

+10

이론적으로 제한이 없지만 실제로는 RAM과 같은 일부 제한된 리소스에 의해 결정되는 약간의 제한이 있습니다. 한도에 이르면 더 큰 문제가 생길 수 있으므로 걱정하지 않으셔도됩니다. –

+3

두 번째 질문은 정확히 몇 개의 템플릿 인수가 있는지보다는 나머지 코드에 더 의존하기 때문에 대답하기가 어렵습니다. stuff compile time을 계산하기 위해 많은 템플릿 인자를 사용한다면, 어떤 코드도 생성되지 않을 수도 있습니다. 그렇지 않으면 코드가 생성되는 경우 인스턴스화 수는 곱셈 요소가됩니다. 이것은 비 변형 템플릿과 다르지 않습니다. –

+12

C++ 11 Standard의 Annex B (Implementation 수량)는 * variadic * 템플릿에 대해서는 특별히 언급하지 않았지만 적어도 256 개의 함수 매개 변수와 1024 개의 템플릿 매개 변수를 권장합니다. 그러나 맹 글링 된 이름이 너무 길어질수록 문제가 생길 수 있습니다. – Oberon

답변

10

필자는 특정 컴파일러 (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 템플릿을 사용하면 재귀를 쉽게 수행 할 수 있지만 컴파일러는 중간 유형을 쉽게 제거 할 수 있습니다. 나는 단지 그것을 시도하고 볼 것을 제안 할 수있다.

+0

내가 사용하고있는 템플릿 인수의 수 (생성 된 코드에서)는 고객에 따라 다르므로 제한이 없습니다. 따라서 내 대답 boost :: mpl이 제한을 피하기 위해 사용하는 것이 좋습니다. –