我试图开发自己的三维渲染器,我需要一个三维矢量结构。要做到这一点,我需要得到一个Vector<3,double>,将其乘以一个4x 4矩阵,然后将其转换为Vector<2,int>,表示屏幕上像素的坐标。
template <size_t DIM, typename T>
struct Vec
{
// Vector components
T data[DIM];
Vec() : data() {}
Vec(std::vector<T> _data)
{
assert(_data.size() == DIM);
for (int i = DIM; i--; data[i] = _data[i])
;
}
// Convert Vec<DIM, T> -> Vec<DIM, U>
template <typename U>
Vec(Vec<DIM, U> &v)
{
for (int i = 0; i < DIM; i++)
data[i] = (T)v[i];
}
T &operator[](size_t idx)
{
return data[idx];
}
};
template <size_t LEN, size_t DIM, typename T>
Vec<LEN, T> embed(const Vec<DIM, T> &v, T fill = 1)
{
Vec<LEN, T> ret;
for (size_t i = LEN; i--; ret[i] = (i < DIM ? v[i] : fill))
;
return ret;
}
template <size_t LEN, size_t DIM, typename T>
Vec<LEN, T> proj(const Vec<DIM, T> &v)
{
Vec<LEN, T> ret;
for (size_t i = LEN; i--; ret[i] = v[i])
;
return ret;
}
但当我尝试这样做时:
int main()
{
Vec<3, float> x({0.8, 4.3, 3.3});
Vec<4, float> v0 = embed<4>(x);
Vec<2, float> v1 = proj<2>(v0);
Vec<2, int> y = (Vec<2, int>)(v1);
std::cout << x[0] << '\n';
std::cout << y[0] << '\n';
return 0;
}
我得到这个错误:
main.cpp: In instantiation of ‘Vec<LEN, T> embed(const Vec<DIM, T>&, T) [with long unsigned int LEN = 4; long unsigned int DIM = 3; T = float]’:
main.cpp:55:31: required from here
main.cpp:38:49: error: passing ‘const Vec<3, float>’ as ‘this’ argument discards qualifiers [-fpermissive]
38 | for (size_t i = LEN; i--; ret[i] = (i < DIM ? v[i] : fill))
| ~^
main.cpp:28:5: note: in call to ‘T& Vec<DIM, T>::operator[](size_t) [with long unsigned int DIM = 3; T = float; size_t = long unsigned int]’
28 | T &operator[](size_t idx)
| ^~~~~~~~
这是什么意思?如何避免这个错误?谢谢!
1条答案
按热度按时间z9smfwbn1#
const Vec<DIM, T> &v
-这是对常量向量的引用。T &operator[](size_t idx)
-这是一个非常数向量的下标运算符。添加另一个重载的下标运算符
const T &operator[](size_t idx) const
-这是一个常量向量的下标运算符:使用C++23中的Explicit对象参数(推导
this
),您将能够将两个下标运算符替换为一个:GCC和Clang还不支持这个C+23特性,MSVC支持
/std:c++latest
,但不支持/std:c++23
:https://godbolt.org/z/onr7GK6x5。查看编译器支持的功能:C++23 core language features。该错误说明:对于
const Vec<DIM, T> &v
,v
函数成员中的this
是const Vec<DIM, T> *this
,并且T &operator[](size_t idx)
不能用于常量向量对象。