- 大学作业 -
我已经使用了如下所示的泛型函数:
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;
我也在const
中使用operator<<
这个类,一切都很好,没有与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 &'
虽然我确实google了,但发现我是否在这些函数前放了另一个const
:
const T1& GetElement1(int index)const { return _elements1[index]; }
const T2& GetElement2(int index)const { return _elements2[index]; }
错误消失了。
当然,这解决了我的问题,但我宁愿知道为什么会发生这种情况以及究竟发生了什么。如果有一种简单的方法来解释我提供的两个例子之间的区别,我们将非常感激。
答案 0 :(得分:1)
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;
}
答案 1 :(得分:1)
在第一个Collection
版本中,_elements1[index]
的类型为int *const&
。这个const
是因为您在_elements1
方法中访问const
(在这种情况下实际this
为const
),这也意味着您不能修改_elements1[index]
。当您取消引用_elements1[index]
时,您将获得int&
,这是_elements1[index]
指向的内容。所以你可以从GetElement1返回它,返回T1&
。
现在到你的第二个Collection课程。 _elements1[index]
方法内部的GetElement1
类型为const int&
,因为在const方法中访问_elements1之前添加了const。现在出现错误的原因是因为您无法将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]