다른 답변은 대체 방법을 잘 다루고 있지만 아무도 enum
(또는 static const int
)이 필요한 이유를 설명하지 못했습니다.
#include <iostream>
int Factorial(int n)
{
if (n == 0)
return 1;
else
return n * Factorial(n-1);
}
int main()
{
std::cout << Factorial(5) << std::endl;
std::cout << Factorial(10) << std::endl;
}
쉽게 이해 할 수 있어야한다 :
먼저 다음 템플릿이 아닌 동등한를 고려한다. 그러나 계승 값이 런타임에 계산된다는 단점이 있습니다. 즉, 프로그램을 실행 한 후 컴파일러가 순환 함수 호출 및 계산을 실행합니다.
템플릿 접근법은 컴파일시 동일한 계산을 수행하고 그 결과를 결과 실행 파일에 저장하는 것입니다. 즉, 예를 들어 당신이 모두 뭔가 결의를 발표 :
int main()
{
std::cout << 120 << std::endl;
std::cout << 3628800 << std::endl;
}
그러나 그것을 달성하기 위해, 당신은 '트릭'은 계산을 수행에 컴파일러에 있습니다. 그렇게하기 위해서는 결과를 어딘가에 저장해야합니다.
enum
정확히 그렇게하기 위해 있습니다. 나는 이 작동하지 않을 것이라고 지적함으로써 그곳에을 설명하려고 노력할 것입니다.
int
정규식을 사용하려고 시도하면 int
과 같은 비 정적 멤버는 인스턴스화 된 개체에서만 의미가 있기 때문에 작동하지 않습니다. 그리고 이렇게 값을 할당 할 수는 없지만 대신 생성자에서 값을 할당 할 수 있습니다. 일반 int
은 작동하지 않습니다.
대신 인스턴스가 생성되지 않은 클래스에서 액세스 할 수있는 무언가가 필요합니다. 시도해 볼 수 있습니다 static int
하지만 여전히 작동하지 않습니다.실제로 아웃 오브 라인, 코드가 컴파일하지만 두 0
의 발생합니다 그 정의를 넣으면
c.cxx:6:14: error: non-const static data member must be initialized out of line
static int value=n*Factorial<n-1>::value ;
^ ~~~~~~~~~~~~~~~~~~~~~~~
: clang
당신에게 문제의 매우 간단한 설명을 제공합니다. 이 형식은 값의 계산을 프로그램 초기화로 지연시키고 올바른 순서를 보장하지 않기 때문입니다. 계산되기 전에 Factorial<n-1>::value
초가 획득되어 0
이 반환되었을 가능성이 높습니다. 또한, 그것은 여전히 우리가 실제로 원하는 것이 아닙니다.
마지막으로 static const int
을 입력하면 예상대로 작동합니다. 컴파일 시간에 static const
을 계산해야하기 때문에 그게 바로 우리가 원하는 것입니다. 이제 다시 코드를 입력하자 : 당신이 Factorial<5>
의 인스턴스를
#include <iostream>
template <unsigned n>
struct Factorial
{
static const int value=n*Factorial<n-1>::value ;
};
template <>
struct Factorial<0>
{
static const int value=1;
};
int main()
{
std::cout << Factorial<5>::value << std::endl;
std::cout << Factorial<10>::value << std::endl;
}
우선; static const int
컴파일러가 컴파일 타임에 해당 값을 계산해야합니다. 실제로 다른 값을 계산해야하는 경우 Factorial<4>
유형을 인스턴스화합니다. 그리고이 값은 Factorial<0>
에 도달 할 때까지 계속됩니다.이 값은 더 많은 인스턴스를 생성하지 않고 계산할 수 있습니다.
그래서, 그것은 대체 방법과 설명이었습니다. 코드를 이해하는 데 최소한 도움이 되었기를 바랍니다.
내가 처음에 게시 한 재귀 함수 대신이 템플릿을 사용할 수 있습니다. 당신은 대체 : 전문화 struct Factorial<0>
와
static const int value = ...
와
return x;
, t<x-1>::value
와
f(x-1)
,
- 및
if (n == 0)
.
그리고 이미 지적 된 바와 같이 enum
자체에 대한,이 static const int
같은 동작을 시행 할 예에서 사용 된. 모든 enum
값을 컴파일 할 때 알 필요가 있으므로 컴파일시에 모든 요청 된 값을 계산해야하기 때문에 이와 같습니다.
실제로이 질문에 답하지 않고 'enum'을 사용했습니다. – Puppy
@Nawaz는 분명히 답을 알고 있지만 명확히 진술하지는 않았습니다. 일부 컴파일러에서'static const int'는 컴파일 타임 상수 인 ** 보증되지 않습니다. 왜냐하면 pre-C++ 11 표준은 컴파일러가이를 해결하기 위해 철저한 시도를하지 않기 때문입니다. 따라서,'Factorial'에서와 같이 ** 템플릿 인자로'value'를 사용하려고하면 컴파일러가'value'의 인스턴스를 constexpr으로 만들지 않기로 결정했기 때문에 실패 할 것입니다. –
rwong