이 질문은 (간접적으로) 표현 템플릿이 포함되어 있으므로 C++ 템플릿 메타 프로그래밍에 대한 지식이 필요합니다. 나는 직접적으로 표현 템플릿에 대한 질문이 아니기 때문에 간접적으로 말하지만 C++ 유형의 계산을 포함한다. 그것이 무엇인지 모르는 경우이 질문에 대답하지 마십시오.컴파일러에서 사용할 최종 형식 선택
충분한 배경 지식없이 질문을하지 않으려면 내가 해결하려고하는 일반적인 문제에 대해 좀 더 자세하게 설명하고 더 구체적인 부분으로 이동하십시오.
사용자가 int
과 같이 계산할 수있는 Integer
을 제공하는 라이브러리가 있다고 가정합니다. int
에서 Integer
을 구성 할 수 있습니다. 그냥 좋아 :
template<class T>
class Integer {
// cut out
};
그래서 내가 원하는대로 정수 유형을 정의 할 수 있습니다 :
Integer<int> i(2);
내부적 내 Integer
클래스는 클래스 템플릿입니다.
이제 API를 변경하지 않고, 내가 Integer
가 int
로 구성 된 경우는 다른 유형에 의해 내부적으로 표현되어야하는 방식으로 라이브러리를 변경하려면, IntegerLit
을 을 말한다. 그 이유는 Integer
의 인스턴스가 int
(int
인수로 기본 포인터 + 개별 데이터로 설명 된 일반 개체 대신 함수에 전달 될 수 있음)에서 생성되었음을 알고 일부 계산 속도를 높일 수 있기 때문입니다. 단지 주석으로.)
내가 int
아닌지로 구성 여부에 따라 다른 코드 경로를 취하도록 컴파일러를 필요 때문에 int
에서 구성 할 때 유형 다른 것이 필수적이다. 런타임 데이터 플래그로는이 작업을 수행 할 수 없습니다. (이유는 짧습니다 : 컴파일러는 int
또는 위에서 언급 한보다 일반적인 유형의 객체를 사용하는 함수를 생성합니다.
문제가 발생했다는 것을 알았습니다. 이 :
Integer<int> a,b(2);
a = b + b;
여기
a
일반
Integer
및
b
전문
IntegerLit
해야합니다. 그러나, 내 문제는 사용자가 자신의 변수를 정의하는 데 매우 동일한 유형
Integer
을 자유롭게 사용할 수 있기 때문에이를 C++로 표현하는 방법입니다.
유형을 다형성으로 만드는 것, 즉 을 Integer
에서 파생시키는 것은 작동하지 않습니다. 잠시 괜찮아 보인다. 그러나 기본 클래스이기 때문에 사용자가 Integer
(기본 클래스)의 인스턴스를 작성하므로 컴파일러는 표현식 트리에 스틱을 붙입니다. (이것이 표현 템플릿이 질문에 포함 된 이유입니다.) 따라서 두 경우 모두 다시 구분할 수 없습니다. 라틴어로 RTTI 체크를하는 것은 내가 그 시점에서 원하는 것만은 아니다.
더욱 유망한 점은 int
으로 구성된 경우 리터럴 템플릿 매개 변수 bool lit
을 유형에 추가하는 것입니다. 요점은 리터럴이 아닌 변환 규칙을 지정하지 않고 다른 경우에 대해 지정하는 것입니다.
그러나 나는 그것을 작동시킬 수 없습니다. 다음 코드는 int
에서 생성하지 않으면 (GCC 4.7 C++ 11) 만 컴파일합니다. 그렇지 않으면 정수가 true
으로 지정되어 있지 않으므로 lit
의 값으로 실패합니다. 따라서 컴파일러는 변환 규칙이없는 기본 구현을 검색합니다. int
에서 생성 할 때 API를 변경하고 Integer<int,true>
을 작성해야하는 옵션은 아닙니다.
template<class T,bool lit=false>
class Integer
{
public:
Integer() {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
T F;
};
template<>
template<class T>
class Integer<T,true>
{
public:
Integer(int i) {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
T F;
};
저는 C++에서 이와 같은 것이 가능한지 궁금합니다.
여기서 도움이 될 수있는 C++ 11의 새로운 기능이 있습니까?
'Integer'는 클래스 템플릿이고 객체를 만들기 위해서는 템플릿 인자가 필요하기 때문에 코드는 일반적으로 유효하지 않습니다. 'Integer a (2);'는 오류입니다. – Xeo
맞아, 여기 간단 해. 실제로 사용자는'typedef'-ed 유형을 사용합니다.이 유형은 'Integer'와 with 및 int를 전문으로합니다. – ritter
'int'로부터 생성하거나 정수 리터럴로부터 생성하는 것을 의미합니까? 중요한 차이가 있습니다. –