我有一个带向量指针的类模板,我需要写一个 size()
函数,返回指向的向量的大小。
目前我的 size()
不能正常工作,我不知道为什么。
的大小 firstView
不等于指向的向量。
#include <vector>
struct functor {
int operator()(int i) const {
return i;
}
};
template<typename T, typename Function> class view {
const std::vector<T>* vectT;
Function functor{};
public:
view(const std::vector<T> vect) {
vectT = &vect;
}
int size() const {
return vectT->size();
}
};
int main() {
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
view<int, functor> firstView(v);
std::cout << firstView->size();
}
你忘了通过引用来传递。 用
view(const std::vector<T> vect) {
vectT = &vect;
}
你做了一个副本,你的指针指向那个副本,一旦constrcutor结束,这个副本就会被销毁。 使用一个像
view(std::vector<T>& vect) {
vectT = &vect;
}
将意味着你的指针指向你传递给构造函数的向量。
有一个错别字 std::cout << firstView->size();
,应该是 std::cout << firstView.size();
.
乍一看一切都很好,而你所描述的问题却无法重现。
Output: 4
然而,在优化的编译中,这个问题就变得很明显了。
https:/godbolt.orgzupeGq9 有优化 -O3
.
Output: 1049747
发生的事情是这样的 v
是作为一个副本传递的,在优化版本中,这个副本会比普通版本更早被销毁并变得不可访问,所以在 size()
你访问的是一个未初始化的指针。
这可以通过引用传递向量来轻松解决。
view(const std::vector<T>& vect){/*...same...*/}
https:/godbolt.orgzsoX36k。 有优化 -O3
.
Output: 4
这样做比较好,不仅因为它解决了与过早销毁访问对象有关的问题,而且还因为你避免了不必要的复制。
正如你在汇编中所看到的,这使得你的程序稍微灵活一些,尽管这只有在一个较大的程序中才会真正明显。