2017-03-27 1 views
0

하나의 유형 인스턴스를 다른 유형 (예 : Matrix<int> ~ Matrix<double>)으로 쉽게 변형 할 수있는 템플릿 매트릭스 클래스가 있습니다. 나에게캐스트 템플릿 (매트릭스) 클래스

#ifndef MATRIX_H 
#define MATRIX_H 

#include <cstdlib> 
#include <vector> 

template <class T> class Matrix 
{ 

    private: 

    std::vector<T>  _data; 
    std::vector<size_t> _shape; 
    std::vector<size_t> _strides; 

    public: 

    Matrix    (const Matrix<T> &) = default; 
    Matrix<T>& operator= (const Matrix<T> &) = default; 

    Matrix<T>(){}; 

    // explicit constructor 
    Matrix<T>(size_t nrow , size_t ncol) 
    { 
     _shape.push_back(nrow); 
     _shape.push_back(ncol); 

     while (_data.size()<_shape[0]*_shape[1]) 
     _data.push_back((T)0); 
    }; 

    T& operator[] (size_t i) 
    { return _data[i]; }; 

    T& operator() (size_t i, size_t j) 
    { return _data[i*_shape[1]+j]; }; 

    size_t size (void) const 
    { return _data.size(); }; 

    std::vector<size_t> shape (void) const 
    { 
     std::vector<size_t> ret(2); 
     for (size_t i=0 ; i<2 ; i++) 
     ret[i] = _shape[i]; 
     return ret; 
    }; 

}; 

#endif 

이 가장 직관적 인 방법은 (X 컴파일하지 않는 옵션 아래 NB 라인) 다음과 같은 두 가지 옵션 중 하나입니다 : 다음과 같이

클래스를 포함하는 헤더 파일 보인다

나는 (내가 사소한 일에 너무 정의 때문에 약 슈퍼 좋아 아니에요) 다음과 같은 솔루션을 사용하는 순간
#include "matrix.h" 

int main (void) 
{ 
    Matrix<int> matInt({5,5}); 

    for (size_t i=0 ; i<matInt.size() ; i++) 
    matInt[i] = static_cast<int>(i); 

    // Option 1 
    Matrix<double> matDouble = matInt; 

    // Option 2 
    Matrix<double> matDouble = static_cast<Matrix<double>>(matInt); 

    return 0; 
} 

:

Matrix<double> as_double (void) { 
    Matrix<double> out(this->shape()); 

    for (size_t i=0 ; i<this->size() ; i++) 
    out[i] = static_cast<double>(_data[i]); 

    return out; 
} 

답변

1

std::vector<T>std::vector<U>에 할당 할 수 없으므로 멤버를 할당 할 수는 없지만 명시 적으로 변환해야합니다.

당신이 쓸 수있는 conversion operator

template<typename U, 
typename V = T, typename = typename std::enable_if<std::is_convertible<T, U>::value>::type> 
operator Matrix<U>() { 
    Matrix<U> mat(shape()[0], shape()[1]); 
    for (size_t i = 0 ; i < size() ; ++i) { 
     mat[i] = static_cast<T>(_data[i]); 
    } 
    return mat; 
} 

enable_if (#include <type_traits>)을 제거 할 수 있지만, 즉 Matrix<std::string> mat = Matrix<int>();

의 침묵 통과를 허용하지 있기 때문에 아마 좋은 생각 나는 조언이 그것을 유지하기 위해 현재 불필요한 알고리즘 복잡성이 있으므로 _data.resize(_shape[0] * _shape[1]);을 사용하십시오.

1

"템플릿 복사 생성자"(일종의)를 정의해야합니다. 기존 생성자를 정리하면 다음과 같습니다.

Matrix<T>(size_t nrow , size_t ncol) 

이것은 필요하지 않습니다. 그런 다음

Matrix(size_t nrow , size_t ncol) 

템플릿 기반 의사 복사 생성자 정의 : 당신은 단순히으로 인라인 생성자를 선언 할 수 있습니다 지금

template<typename From> 
Matrix(const Matrix<From> &s) 

을, 당신이 복사 생성자를 작성하는 것처럼이 생성자를 작성합니다.

그 후, 당신은 또한, 다시 템플릿 기반 할당 연산자

template<typename From> 
Matrix &operator=(const Matrix<From> &f) 

쓰기이 일반 할당 연산자 인 척하고, 하나를 구현하는 움직임을 통해 이동합니다.