转换为基类时调用的模板超类构造函数
Template superclass constructor called when converting to base
我正在尝试为线性代数程序编写一个实用头文件,它主要用于学习,所以我更关心易用性而不是效率。
无论如何,我的想法是我有一个 Matrix
类型和一个继承自 Matrix
的 Vector
类型。因为我想添加一些专门针对3D情况的功能,而不是重写整个class,我还有一个_Vector
class,它意味着通用和特殊都可以继承类型。
以下是失败的最小示例:
(fails.hpp)
#include <string>
template <int M, int N, typename FloatType = double>
class Matrix {
public:
inline Matrix() : data{0}{}
protected:
FloatType data[M * N];
};
template <int DIM, typename FloatType>
class _Vector : public Matrix<DIM, 1, FloatType> {
public:
template <typename ...FloatTypes>
inline constexpr _Vector(const FloatTypes... values)
: Matrix<sizeof...(FloatTypes), 1, FloatType>()
{
int i = 0;
((Matrix<DIM, 1, FloatType>::data[i++] = values), ...);
}
inline FloatType operator [](const int index) {
return Matrix<DIM, 1, FloatType>::data[index];
}
inline operator std::string () const {
std::string tmp = "[ ";
for (int i = 0; i < DIM; i++) {
tmp += std::to_string(Matrix<DIM, 1, FloatType>::data[i]) + " ";
}
tmp += "]\n";
return tmp;
}
};
template<int DIM, typename FloatType = double>
class Vector : _Vector<DIM, FloatType> {
template <typename ...FloatTypes>
inline constexpr Vector(const FloatTypes... values) : _Vector<DIM, FloatType>(values...) {}
};
template <typename ...FloatTypes>
Vector(const FloatTypes...) -> Vector<sizeof...(FloatTypes), std::common_type_t<FloatTypes...>>;
template <typename FloatType>
class Vector<3, FloatType> : public _Vector<3, FloatType> {
public:
FloatType& x = Matrix<3, 1, FloatType>::data[0];
FloatType& y = Matrix<3, 1, FloatType>::data[1];
FloatType& z = Matrix<3, 1, FloatType>::data[2];
template <typename ...FloatTypes>
inline constexpr Vector(const FloatTypes... values) : _Vector<3, FloatType>(values...) {}
// cross product
inline Vector operator ^(_Vector<3, FloatType>& other) {
Vector V;
V.x = y * other[2] - z * other[1];
V.y = z * other[0] - x * other[2];
V.z = x * other[1] - y * other[0];
return V;
}
};
(main.cpp)
#include <fails.hpp>
//#include <works.hpp>
#include <iostream>
int main() {
Vector v1 = { 1., 2., 3. };
Vector v2 = { 3., 2., 1. };
std::cout << (std::string)(v1 ^ v2);
}
我不明白的是,如果我从 Matrix
类型中删除继承,它会解决问题:
(works.hpp)
#include <string>
template <int DIM, typename FloatType>
class _Vector {
public:
template <typename ...FloatTypes>
inline constexpr _Vector(const FloatTypes... values)
{
int i = 0;
((data[i++] = values), ...);
}
inline FloatType operator [](const int index) {
return data[index];
}
inline operator std::string () const {
std::string tmp = "[ ";
for (int i = 0; i < DIM; i++) {
tmp += std::to_string(data[i]) + " ";
}
tmp += "]\n";
return tmp;
}
protected:
FloatType data[DIM];
};
template<int DIM, typename FloatType = double>
class Vector : _Vector<DIM, FloatType> {
template <typename ...FloatTypes>
inline constexpr Vector(const FloatTypes... values) : _Vector<DIM, FloatType>(values...) {}
};
template <typename ...FloatTypes>
Vector(const FloatTypes...) -> Vector<sizeof...(FloatTypes), std::common_type_t<FloatTypes...>>;
template <typename FloatType>
class Vector<3, FloatType> : public _Vector<3, FloatType> {
public:
FloatType& x = Vector<3, FloatType>::data[0];
FloatType& y = Vector<3, FloatType>::data[1];
FloatType& z = Vector<3, FloatType>::data[2];
template <typename ...FloatTypes>
inline constexpr Vector(const FloatTypes... values) : _Vector<3, FloatType>(values...) {}
// cross product
inline Vector operator ^(_Vector<3, FloatType>& other) {
Vector V;
V.x = y * other[2] - z * other[1];
V.y = z * other[0] - x * other[2];
V.z = x * other[1] - y * other[0];
return V;
}
};
当我用 g++ -I. main.cpp -std=c++17
编译时,我得到这个输出:
n file included from main.cpp:1:
./fails.hpp: In instantiation of ‘constexpr _Vector<DIM, FloatType>::_Vector(const FloatTypes ...) [with FloatTypes = {}; int DIM = 3; FloatType = double]’:
./fails.hpp:54:88: required from ‘Vector<3, FloatType> Vector<3, FloatType>::operator^(_Vector<3, FloatType>&) [with FloatType = double]’
main.cpp:9:35: required from here
./fails.hpp:58:12: in ‘constexpr’ expansion of ‘V.Vector<3, double>::Vector<>()’
./fails.hpp:16:51: error: type ‘Matrix<0, 1, double>’ is not a direct base of ‘_Vector<3, double>’
16 | : Matrix<sizeof...(FloatTypes), 1, FloatType>()
|
我完全不知道继承是如何改变这种情况的,但现在看来 _Vector
class 构造函数被调用是出于某种原因(当时使用了错误的模板参数)。我不知道要搜索什么,所以如果你能解释为什么会导致这个问题,以及一般来说这是什么类型的问题,我将非常感激。
谢谢!
你的_Vector<int DIM, typename FloatType>
继承了Matrix<DIM, FloatType>
,但是它的构造函数使用sizeof...(FloatTypes)
作为Matrix
的第一个模板参数
template <int DIM, typename FloatType>
class _Vector : public Matrix<DIM, 1, FloatType>
public:
template <typename ...FloatTypes>
constexpr _Vector(const FloatTypes... values)
: Matrix<sizeof...(FloatTypes), 1, FloatType>();
};
这意味着当 DIM
不等于 sizeof...(FloatTypes)
时,您的 _Vector
初始化一个 不 从它继承的基,您应该将构造函数定义为
template <typename ...FloatTypes>
constexpr _Vector(const FloatTypes... values)
: Matrix<DIM, 1, FloatType>();
我正在尝试为线性代数程序编写一个实用头文件,它主要用于学习,所以我更关心易用性而不是效率。
无论如何,我的想法是我有一个 Matrix
类型和一个继承自 Matrix
的 Vector
类型。因为我想添加一些专门针对3D情况的功能,而不是重写整个class,我还有一个_Vector
class,它意味着通用和特殊都可以继承类型。
以下是失败的最小示例: (fails.hpp)
#include <string>
template <int M, int N, typename FloatType = double>
class Matrix {
public:
inline Matrix() : data{0}{}
protected:
FloatType data[M * N];
};
template <int DIM, typename FloatType>
class _Vector : public Matrix<DIM, 1, FloatType> {
public:
template <typename ...FloatTypes>
inline constexpr _Vector(const FloatTypes... values)
: Matrix<sizeof...(FloatTypes), 1, FloatType>()
{
int i = 0;
((Matrix<DIM, 1, FloatType>::data[i++] = values), ...);
}
inline FloatType operator [](const int index) {
return Matrix<DIM, 1, FloatType>::data[index];
}
inline operator std::string () const {
std::string tmp = "[ ";
for (int i = 0; i < DIM; i++) {
tmp += std::to_string(Matrix<DIM, 1, FloatType>::data[i]) + " ";
}
tmp += "]\n";
return tmp;
}
};
template<int DIM, typename FloatType = double>
class Vector : _Vector<DIM, FloatType> {
template <typename ...FloatTypes>
inline constexpr Vector(const FloatTypes... values) : _Vector<DIM, FloatType>(values...) {}
};
template <typename ...FloatTypes>
Vector(const FloatTypes...) -> Vector<sizeof...(FloatTypes), std::common_type_t<FloatTypes...>>;
template <typename FloatType>
class Vector<3, FloatType> : public _Vector<3, FloatType> {
public:
FloatType& x = Matrix<3, 1, FloatType>::data[0];
FloatType& y = Matrix<3, 1, FloatType>::data[1];
FloatType& z = Matrix<3, 1, FloatType>::data[2];
template <typename ...FloatTypes>
inline constexpr Vector(const FloatTypes... values) : _Vector<3, FloatType>(values...) {}
// cross product
inline Vector operator ^(_Vector<3, FloatType>& other) {
Vector V;
V.x = y * other[2] - z * other[1];
V.y = z * other[0] - x * other[2];
V.z = x * other[1] - y * other[0];
return V;
}
};
(main.cpp)
#include <fails.hpp>
//#include <works.hpp>
#include <iostream>
int main() {
Vector v1 = { 1., 2., 3. };
Vector v2 = { 3., 2., 1. };
std::cout << (std::string)(v1 ^ v2);
}
我不明白的是,如果我从 Matrix
类型中删除继承,它会解决问题:
(works.hpp)
#include <string>
template <int DIM, typename FloatType>
class _Vector {
public:
template <typename ...FloatTypes>
inline constexpr _Vector(const FloatTypes... values)
{
int i = 0;
((data[i++] = values), ...);
}
inline FloatType operator [](const int index) {
return data[index];
}
inline operator std::string () const {
std::string tmp = "[ ";
for (int i = 0; i < DIM; i++) {
tmp += std::to_string(data[i]) + " ";
}
tmp += "]\n";
return tmp;
}
protected:
FloatType data[DIM];
};
template<int DIM, typename FloatType = double>
class Vector : _Vector<DIM, FloatType> {
template <typename ...FloatTypes>
inline constexpr Vector(const FloatTypes... values) : _Vector<DIM, FloatType>(values...) {}
};
template <typename ...FloatTypes>
Vector(const FloatTypes...) -> Vector<sizeof...(FloatTypes), std::common_type_t<FloatTypes...>>;
template <typename FloatType>
class Vector<3, FloatType> : public _Vector<3, FloatType> {
public:
FloatType& x = Vector<3, FloatType>::data[0];
FloatType& y = Vector<3, FloatType>::data[1];
FloatType& z = Vector<3, FloatType>::data[2];
template <typename ...FloatTypes>
inline constexpr Vector(const FloatTypes... values) : _Vector<3, FloatType>(values...) {}
// cross product
inline Vector operator ^(_Vector<3, FloatType>& other) {
Vector V;
V.x = y * other[2] - z * other[1];
V.y = z * other[0] - x * other[2];
V.z = x * other[1] - y * other[0];
return V;
}
};
当我用 g++ -I. main.cpp -std=c++17
编译时,我得到这个输出:
n file included from main.cpp:1:
./fails.hpp: In instantiation of ‘constexpr _Vector<DIM, FloatType>::_Vector(const FloatTypes ...) [with FloatTypes = {}; int DIM = 3; FloatType = double]’:
./fails.hpp:54:88: required from ‘Vector<3, FloatType> Vector<3, FloatType>::operator^(_Vector<3, FloatType>&) [with FloatType = double]’
main.cpp:9:35: required from here
./fails.hpp:58:12: in ‘constexpr’ expansion of ‘V.Vector<3, double>::Vector<>()’
./fails.hpp:16:51: error: type ‘Matrix<0, 1, double>’ is not a direct base of ‘_Vector<3, double>’
16 | : Matrix<sizeof...(FloatTypes), 1, FloatType>()
|
我完全不知道继承是如何改变这种情况的,但现在看来 _Vector
class 构造函数被调用是出于某种原因(当时使用了错误的模板参数)。我不知道要搜索什么,所以如果你能解释为什么会导致这个问题,以及一般来说这是什么类型的问题,我将非常感激。
谢谢!
你的_Vector<int DIM, typename FloatType>
继承了Matrix<DIM, FloatType>
,但是它的构造函数使用sizeof...(FloatTypes)
作为Matrix
template <int DIM, typename FloatType>
class _Vector : public Matrix<DIM, 1, FloatType>
public:
template <typename ...FloatTypes>
constexpr _Vector(const FloatTypes... values)
: Matrix<sizeof...(FloatTypes), 1, FloatType>();
};
这意味着当 DIM
不等于 sizeof...(FloatTypes)
时,您的 _Vector
初始化一个 不 从它继承的基,您应该将构造函数定义为
template <typename ...FloatTypes>
constexpr _Vector(const FloatTypes... values)
: Matrix<DIM, 1, FloatType>();