问题描述
给定一个矩阵模板类 mat<M,N,T>
,以下成员函数允许我有效地转置行向量或列向量,因为它们具有相同/对应的内存占用:
template<int M,int N=M,typename T = double>
struct mat {
// ...
template<int Md = M,int Nd = N,typename = std::enable_if_t<Md == 1 || Nd == 1>>
const mat<N,M,T>& transposedView() const {
static_assert(M == 1 || N == 1,"transposedView() supports only vectors,not general matrices.");
return *reinterpret_cast<const mat<N,T>*>(this);
}
}
我多年来一直在使用这个函数,出于习惯,开始在临时表达式 (/*vector-valued expression*/).transposedView()
上调用它,忘记了它随后会返回对临时的引用,并导致 GCC 只是一点点的未定义行为我。
是否有一种简单的方法可以让我添加一些在临时调用时会产生某种警告的内容?
或者,只要我不存储引用,临时调用它实际上应该是安全的吗?
解决方法
成员函数可以是qualified for lvalue or rvalue objects。使用它,您可以创建一个重载集,如
template<int M,int N=M,typename T = double>
struct mat {
// ...
template<int Md = M,int Nd = N,typename = std::enable_if_t<Md == 1 || Nd == 1>>
const mat<N,M,T>& transposedView() & const {
static_assert(M == 1 || N == 1,"transposedView() supports only vectors,not general matrices.");
return *reinterpret_cast<const mat<N,T>*>(this);
}
template<int Md = M,T>& transposedView() && const = delete;
}
现在,如果您尝试使用右值对象调用该函数,则会出现编译器错误。