내가 현재C++에서 암시 적 템플릿 인스턴스화
MatrixBase -> DenseMatrix
-> (other types of matrices)
-> MatrixView -> TransposeView
-> DiagonalView
-> (other specialized views of matrices)
MatrixBase
같은 클래스 계층 구조를 가지고있다 연산자() (INT, INT)와 같은 것을 정의 구현을 강제하는 추상 클래스; 2 차원 숫자 배열을 나타냅니다. MatrixView
은 행렬을 전치 시키거나 부분 행렬을 취하는 것과 같이 행렬을 바라 보는 (아마도 변경 가능한) 방법을 나타냅니다. MatrixView
의 점은 말할 수있을 것입니다 뭔가 Diagonal
경량 어댑터의 일종 인 DiagonalView
객체를 반환
Scale(Diagonal(A), 2.0)
있다.
이제 질문이 있습니다. 아주 간단한 행렬 연산을 예제로 사용하겠습니다.
template <class T>
void Scale(MatrixBase<T> &A, const T &scale_factor);
과 같은 함수를 정의하고 싶습니다. 이름에서 알 수있는 분명한 사실은 있습니다. 솔직히 - 투 - 미스 비 - 뷰 행렬 또는 MatrixView
의 서브 클래스 인스턴스를 전달할 수 있기를 원합니다. Diagonal
에 의해 반환 된 DiagonalView
객체가 일시적이며, Scale
임시을 받아 들일 수없는 const가 아닌 참조를 필요하기 때문에 위의 기록으로 프로토 타입은
Scale(Diagonal(A), 2.0);
으로 문이 작동하지 않습니다. 이 일을 할 수있는 방법이 있습니까? 나는 SFINAE를 사용하려고 시도했지만, 모든 것을 잘 이해하지 못하고 문제가 해결 될지 확실하지 않습니다. 이러한 템플릿 함수는 명시 적 템플릿 인수 목록을 제공하지 않고 호출 할 수 있다는 것이 중요합니다 (암시 적 인스턴스 생성을 원합니다). 위의 내용은 이상적으로 서면으로 작동 할 수 있습니다.
편집 : (후속 질문)
SBI이를 rvalue 참조 및 임시직에 대해 아래의 반응으로, 규모의 두 가지 버전을 정의하는 방법이 있나요, 대한 const가 아닌를 rvalue 참조를 필요 하나 뷰가 아닌보기 및 값별보기가 필요한보기? 문제는 암시 적 인스턴스화가 작동하는 방식으로 컴파일 타임에이 둘을 구별하는 것입니다.
업데이트
나는 동안,
ReadableMatrix
WritableMatrix : public ReadableMatrix
WritableMatrixView
DenseMatrix : public WritableMatrix
DiagonalView : public WritableMatrixView
WritableMatrixView
이 WritableMatrix
구별되는 이유보기가 const를 참조로 주위에 전달해야한다는 것입니다에 클래스 계층 구조를 변경 한 행렬 자체는 const가 아닌 ref로 전달되어야하므로 접근 자 멤버 함수는 다른 const를 갖습니다. 이제 스케일 등의 기능을 두 가지 버전하는 const를보기위한 하나의 실제 행렬에 대한 const가 아닌 버전이 있음을
template <class T>
void Scale(const WritableMatrixView<T> &A, const T &scale_factor);
template <class T>
void Scale(WritableMatrix<T> &A, const T &scale_factor){
Scale(WritableMatrixViewAdapter<T>(A), scale_factor);
}
참고로 정의 할 수 있습니다. 이것은 Mult(A, B, C)
과 같은 함수를 의미합니다. 8 오버로드가 필요하지만 적어도 작동합니다. 하지만 작동하지 않는 기능은 다른 기능에서 이러한 기능을 사용하는 것입니다.보시다시피, 각 View
- 같은 클래스에는보고있는 내용의 View
멤버가 포함되어 있습니다. 예를 들어 Diagonal(SubMatrix(A))
이라는 식에서 Diagonal
함수는 A
의 완전 파생 형식을 알아야하는 DiagonalView<SubMatrixView<T> >
유형의 개체를 반환합니다. 이제 Scale
내에서 기본보기 또는 행렬 참조 중 하나를 사용하는 다른 함수를 호출한다고 가정합니다. 필요한 것의 생성이 Scale의 인수의 파생 된 유형을 필요로하기 때문에 실패 할 것입니다. 정보가 없다. 아직도이 문제에 대한 해결책을 찾아야합니다.
업데이트
내가 Scale
같은 함수의 두 가지 버전 중 하나를 선택 효과적으로 부스트의 enable_if의 자체 개발 버전입니다 무엇을 사용하고 있습니다. 그것은 모든 행렬에 라벨을 붙이고, 읽기 쉽고 쓰기가 가능하고 뷰인지 아닌지를 나타내는 여분의 typedef 태그를 사용하여 클래스를 표시합니다. 결국 2^N 오버로드가 여전히 필요하지만 이제 N은 비 const 인수의 수입니다. 최종 결과는 here을 참조하십시오 (심각하게 다시 개정되지는 않습니다).
Scale()이 const 참조에 의한 매개 변수를 허용하지 않는 특별한 이유가 있습니까? – Naveen
스케일은 실제로 인수를 확장해야하므로 const 일 수 없습니다. –
스케일이 왜 임시 매트릭스를 수정합니까? –