일반적인 "서명되지 않은"클래스를 개발했거나 uint8_t
을 매개 변수로 사용하여 C (C++) 기본 제공 서명이없는 클래스 템플릿 Unsigned<size_t N>
을 개발했습니다. 예를 들어, Unsigned<4>
은 uint32_t
과 동일하고 Unsigned<32>
은 존재하는 경우 uint256_t
과 동일합니다.템플릿 : 런타임시 유형화되지 않은 매개 변수에서 인스턴스화 (및 참조)?
지금까지 나는 빌트인 부호없는 (특히 sizeof(Natural<N>)==N
, (Natural<N>(-1) == "max_value_all_bits_1" == ~Natural<N>(0))
), abs(), sign(), div (사용자 정의 div_t 구조체 사용)와의 호환성에 대한 대부분의 설명을 따르지 않았다.), ilogb() (GCC 전용) 및 numeric_limits <>를 사용합니다.
그러나 클래스 템플릿은 템플릿이기 때문에 템플리트 형식은 관련이 없으므로 문제가 있습니다. 템플릿에 형식이 지정되지 않은 매개 변수에는 "컴파일시 상수"가 필요합니다. 방법이 "const
"보다 엄격합니다. 나는 본질적으로 을 알 수 없으므로 서명되지 않은 N을 만들 수 없습니다. 나는이 같은 코드를 가질 수 없습니다 즉
:
...
(... assuming all adequate headers are included ...)
using namespace std;
using lpp::Unsigned;
std::string str;
cout<< "Enter an arbitrarily long integer (end it with <ENTER>) :>";
getline(cin, str, '\n');
const int digits10 = log10(str.length()) + 1;
const int digits256 = (digits10 + 1) * ceil(log(10)/log(256)); // from "10×10^D = 256^T"
// at this point, I "should" be able to, semantically, do this:
Unsigned<digits256> num; // <-- THIS I CAN'T -- num would be guaranteed
// big enough to hold str's binary expression,
// no more space is needed
Unsigned::from_str(num, str); // somehow converts (essentially a base change algo)
// now I could do whatever I wanted with num "as if" a builtin.
std::string str_b3 = change_base(num, 3); // a generic implemented somehow
cout<< "The number above, in base 3, is: "<< str_b3<< endl;
...
(A/N - 이것은 "약간 많은 수의"(내가 가진 읽어 부호의있는 TestSuite의 일부입니다 그에 따라 N을 설정 한 후 최대 120 자까지 시도 함) 다른 모든 기지에서 표현하는 것과 같은 작업을 수행합니다.
이 제한을 무시하거나 완화 할 수있는 방법을 모색합니다 , 나는 시도하고 탐구하고 싶은 몇 가지 개념에 뛰어 들고 있었지만, 나는 너무 많은 노력을 대안으로 사용하고 싶지 않다. 더 복잡한 것을 만들거나 클래스의 행동을 너무 많이 벗어나게 만들뿐입니다.
내가 처음 생각한 것은 내가 선택한 것의 Unsigned<N>
을 선택할 수 없다면 적절한 생성자로 이어질 N 개의 사전 선택된 값 집합에서 선택할 수있었습니다. 런타임에 호출되지만 컴파일 시간 값에 따라 달라집니다.
???? GetMeAnUnsigned (size_t S) {
switch (S) {
case 0: { throw something(); } // we can't have a zero-size number, right?
case 1, 2, 3, 4: { return Unsigned<4>(); break; }
case 5, 6, 7, 8: { return Unsigned<8>(); break; }
case 9, 10, 11, 12, 13, 14, 15, 16: { return Unsigned<16>(); break; }
....
default: { return Unsigned<128>(); break; } // wow, a 1Kib number!
} // end switch
exit(1); // this point *shouldn't* be reachable!
} // end function
저는 개인적으로 접근 방식을 좋아합니다. 그러나 반환 형식을 지정하는 데 사용할 수있는 것은 무엇인지 알 수 없습니다. 실제로 문제를 "해결"하지는 않으며 심각성을 어느 정도 저하시킵니다. 인스턴스화가 일 때 컴파일 타임 상수에서 일 때 전환 스위치를 사용하여 트릭을 수행 할 것이라고 확신하는 경우이 발생하는 만 변경됩니다.
반환 형식을 선언하는 유일한 실행 가능한 도움말은이 새로운 C++ 0 (1?) X "decltype"구조 인 것 같습니다.이 구조체를 사용하면 적절한 형식을 얻을 수 있습니다. 올바르게 기능 :
decltype (Unsigned<N>) GetMeAnUnsigned (size_t S) {
.. do some choices that originate an N
return Unsigned<N>();
}
... 또는 이와 비슷한 것. 나는 C++에 입력하지 않았습니까? X는 auto
(iterators의 경우)을 넘지 만, 첫 번째 질문은 이고 decltype
또는과 같은 기능을 사용하면 원하는 것을 얻을 수 있습니까? (런타임 제한하는 경우에도 인스턴스의 선택) 대안에 대한
, 나는 문제가 내 수업 사이의 관계 있다면 나는 그들에게 모든는 "종류-의"자료를 만들 수 있다고 생각했다 템플릿 자체 유도로 : 음, 하나 하지 않습니다, 때문에하지만 ...
template <size_t N>
class Unsigned : private UnsignedCommon { ...
을 나는 내장 - 인 (모두 "-의 종류를"만드는)하는 백 버너에 그 접근 방식을 왼쪽 , 어떤 경우에는 이 일 때 더하기 일반 클래스로 그것을 정적 초기화, 포인터를 반환하고 제대로 호출 할 경우 클라이언트가 파괴해야합니다. 두 번째 질문 : 이 대안을 너무 일찍 폐기하는 것이 잘못 되었습니까?
'sizeof'가 N을 얼마나 중요하게 생각합니까? 당신이 그것을 희생한다면, 템플릿이 아닌 대안들이 있습니다. – Troubadour
"Unsigned Unknown Unknown N"을 목표로한다면 필요에 따라 동적으로 번호에 대한 저장소를 할당 할 수 있습니다. 궁극적으로 사용자가 결과에 필요한 인스턴스화를 파악하지 않고 'big_a + big_b'를 사용하기를 원하지 않습니까? – UncleBens
@Troubadour : "sizeof() == N"불변량은 내가 "[unsigned] ints와 같아지기를 원했을 때 그 타입을 디자인 한 것입니다. 나는 그것을 떨어 뜨릴지도 모른다고 생각하지만, 나는 대부분의 정상적인 대안을 다 써 버린 후에야 마침내 버릴지도 모른다. –