-大学作业-
我已经使用过如下的通用函数:
template<class T1, class T2, int max>
class Collection{
T1* _elements1[max];
T2* _elements2[max];
int _count;
public:
// ctor
bool AddElement(const T1& e1, const T2& e2)
{
for (int i = 0; i < _count; i++)
if (_elements1[i] == e1 && _elements2[i] == e2)
return false;
_elements1[_count] = e1;
_elements2[_count] = e2;
_count++;
return true;
}
int GetMax()const { return max;}
T1& GetElement1(int index)const { return *_elements1[index]; }
T2& GetElement2(int index)const { return *_elements2[index]; }
}
在main()
:中
Collection<int, double, 6> collection;
for (int i = 0; i < 6; i++)
collection.AddElement(i, i + 0.4);
cout << collection << endl;
我还在这个类的operator<<
中使用const
,一切都很好,没有与const
相关的编译器抱怨。
但是,今天我尝试了这门课的稍微不同的版本,我们应该练习,因为它将以某种形式出现在考试中
template<class T1, class T2, int max>
class Collection{
T1 _elements1[max];
T2 _elements2[max];
int _count;
public:
// ctor
int GetMax()const { return max;}
T1& GetElement1(int index)const { return _elements1[index]; }
T2& GetElement2(int index)const { return _elements2[index]; }
}
这里的区别在于,T1
和T2
不是pointers
的数组,而是普通对象的数组,而且在底部,当return
出现时,不需要取消引用。
然而,在后一个例子中,我得到了这个错误:
error C2440: 'return' : cannot convert from 'const int' to 'int &'
尽管我确实用谷歌搜索了一下,发现我是否在这些函数前面放了另一个const
:
const T1& GetElement1(int index)const { return _elements1[index]; }
const T2& GetElement2(int index)const { return _elements2[index]; }
错误消失了。
诚然,这解决了我的问题,但我更愿意了解为什么会发生这种情况,以及幕后到底发生了什么。如果有一种简单的方法来解释我提供的两个例子之间的差异,我们将不胜感激。
在第一个Collection
版本中,_elements1[index]
的类型为int *const&
。这个const
是因为您在const
方法中访问_elements1
(在这种情况下,实际上this
就是const
),也意味着您不允许修改_elements1[index]
。当你取消引用_elements1[index]
时,你会得到int&
,这是_elements1[index]
指向的东西。所以你可以从GetElement1返回它,它返回T1&
。
现在开始你的第二节"收藏"课。这里,GetElement1
方法内部的_elements1[index]
的类型是const int&
,就像之前添加const一样,因为您访问了const方法内部的_elements1。现在出现错误的原因是无法将const int&
隐式转换为int&
。
如果你想了解什么类型的_elements1[index]
在不同的地方,你可以使用以下技巧:
template<typename T>
struct TD;
// ...
T1& GetElement1(int index)const {
TD<decltype(_elements1[index])> tt;
return _elements1[index];
}
将输出错误,里面的确切类型在decltype:之上
error: implicit instantiation of undefined template 'TD<const int &>'
^^^^^^^^^^^ - type of _elements1[index]
T1& GetElement1(int index)const { return _elements1[index]; }
对于成员函数,编译器将把类本身(this)作为第一个参数传递给函数。由于成员函数声明后有const限定符,GetElement1的第一个参数是const Collection,而不是Collection
编辑:
#include "iostream"
#include "string"
template<class T1, class T2, int max>
class Collection{
T1* _elements1[max];
T2* _elements2[max];
int _count;
public:
Collection() {
for (size_t i = 0; i < max; ++i) {
_elements1[i] = new T1{};
_elements2[i] = new T2{};
}
}
int GetMax()const { return max;}
const T1& GetElement1(int index) const {
// _elements1[0] = new T1{}; Error, the pointer is constant
_elements1[0]->resize(5); // Ok, the pointed object isn't constant
return *_elements1[index];
}
const T2& GetElement2(int index) const { return *_elements2[index]; }
};
int main() {
Collection<std::string, std::string, 5> c;
const std::string& rs = c.GetElement1(1);
return 0;
}