У меня возникли проблемы с выяснением того, почему мой частично созданный шаблон не компилируется на C++.C++ Typedef в частичном создании шаблона
Я пытаюсь представить класс, который возвращает различные типы на основе шаблонов, которые передаются ему:
enum EVectorType {
eVectorType_Scalar,
eVectorType_Vector,
eVectorType_Matrix
};
template<
EVectorType kVectorTypeOne,
EVectorType kVectorTypeTwo,
typename TypeOne,
typename TypeTwo>
class MultSwitch {
private:
const TypeOne &m_A;
const TypeTwo &m_B;
public:
typedef TypeOne ResultType;
MultSwitch(const TypeOne &a, const TypeTwo &b)
: m_A(a), m_B(b) { }
ResultType GetMultiplication() const { return m_A * m_B; }
};
Класс используется как перегрузка на *
оператора:
template<typename T>
class VectorTraits {
public:
static const EVectorType kVectorType = eVectorType_Scalar;
};
template<typename T, const int N>
class VectorTraits<VectorBase<T, N> > {
public:
static const EVectorType kVectorType = eVectorType_Vector;
};
template<typename TypeOne, typename TypeTwo>
static inline
typename MultSwitch<
VectorTraits<TypeOne>::kVectorType,
VectorTraits<TypeTwo>::kVectorType,
TypeOne, TypeTwo
>::ResultType
operator*(const TypeOne &v1, const TypeTwo &v2) {
typedef MultSwitch<
VectorTraits<TypeOne>::kVectorType,
VectorTraits<TypeTwo>::kVectorType,
TypeOne, TypeTwo
> VSwitch;
return VSwitch(v1, v2).GetMultiplication();
}
следующие специализации работы по назначению:
template<typename TypeOne, typename TypeTwo>
class MultSwitch<
eVectorType_Scalar,
eVectorType_Vector,
TypeOne, TypeTwo> {
private:
const TypeOne &m_A;
const TypeTwo &m_B;
public:
typedef TypeTwo ResultType;
MultSwitch(const TypeOne &a, const TypeTwo &b)
: m_A(a), m_B(b) { }
ResultType GetMultiplication() const { return ScalarMultiply(m_B, m_A); }
};
template<typename TypeOne, typename TypeTwo>
class MultSwitch<
eVectorType_Vector,
eVectorType_Scalar,
TypeOne, TypeTwo> {
private:
const TypeOne &m_A;
const TypeTwo &m_B;
public:
typedef TypeOne ResultType;
MultSwitch(const TypeOne &a, const TypeTwo &b)
: m_A(a), m_B(b) { }
ResultType GetMultiplication() const { return ScalarMultiply(m_A, m_B); }
};
template<typename TypeOne, typename TypeTwo>
class MultSwitch<
eVectorType_Vector,
eVectorType_Vector,
TypeOne, TypeTwo> {
private:
const TypeOne &m_A;
const TypeTwo &m_B;
public:
typedef typename TypeOne::ScalarType ResultType;
MultSwitch(const TypeOne &a, const TypeTwo &b)
: m_A(a), m_B(b) { }
ResultType GetMultiplication() const { return m_A.Dot(m_B); }
};
Ho Веверу, следующий не будет:
template<typename TypeOne, typename TypeTwo>
class MultSwitch<
eVectorType_Matrix,
eVectorType_Matrix,
TypeOne, TypeTwo> {
private:
const TypeOne &m_A;
const TypeTwo &m_B;
public:
typedef MatrixBase<typename TypeOne::ScalarType, TypeOne::kNumRows, TypeTwo::kNumCols> ResultType;
MultSwitch(const TypeOne &a, const TypeTwo &b)
: m_A(a), m_B(b) { }
ResultType GetMultiplication() const { return m_A.MultiplyMatrix(m_B); }
};
Всякий раз, когда я пишу выражение a * b
где черты типовым a
и b
матча eVectorType_Matrix
, по некоторым причинам, компилятор говорит, что ResultType того же типа, как TypeOne
или a
. Я изменил различные типы typedefs в рабочих специализациях, но все они, похоже, вызывают такую же ошибку.
Более конкретно, следующий код:
template <typename T, const int nRows, const int nCols>
class MatrixBase {
public:
typedef T ScalarType;
static const int kNumRows = nRows;
static const int kNumCols = nRows;
...
};
template<typename T, const int N, const int M>
class VectorTraits<MatrixBase<T, N, M> > {
public:
static const EVectorType kVectorType = eVectorType_Matrix;
};
MatrixBase<int, 2, 3> a;
...
MatrixBase<int, 3, 5> b;
...
MatrixBase<float, 2, 5> amb = a * b;
Выдает следующую ошибку:
TestMatrix.cpp:145:42: error: conversion from ‘MultSwitch<(EVectorType)2u, (EVectorType)2u, MatrixBase<int, 2, 3>, MatrixBase<int, 3, 5> >::ResultType {aka MatrixBase<int, 2, 3>}’ to non-scalar type ‘MatrixBase<float, 2, 5>’ requested
MatrixBase<float, 2, 5> amb = a * b;
Я считаю, что у вас есть две проблемы: (1) В MatrixBase, я думаю, "статический Const ИНТ kNumCols = NROWS;" должен быть «static const int kNumCols = nCols;» (2) «a * b» вернет MatrixBase, а не MatrixBase . Вам нужно будет добавить конструктор копирования для выполнения преобразования int-> float. –
Glenn
Да, я только что поймал. Добавьте его в качестве ответа! У меня уже есть конструктор копирования. :) – Mokosha