2016-05-17 52 views
2

--University homework--返回泛型函数对象的引用(与指针或非指针属性)

我已经与通用功能看起来像这样的工作:

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; 

我也用constoperator<<这个类,一切的伟大工程,与0123没有编译器的投诉。

但是,今天我尝试了这个班的稍微不同的版本,我们应该练习,因为它会以某种形式在考试中。

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]; } 
} 

的此不同的是,T1T2不是的pointers数组,但纯对象数组,并在底部,当return ING,有没有必要取消引用。虽然我做google一下,发现如果我把另一个const在这些功能中的前像这样

error C2440: 'return' : cannot convert from 'const int' to 'int &' 

const T1& GetElement1(int index)const { return _elements1[index]; } 
const T2& GetElement2(int index)const { return _elements2[index]; } 

然而,在后者的例子中,我得到这个错误

错误消失。

当然,这解决了我的问题,但我宁愿了解为什么会发生这种情况以及发生了什么。如果有一个简单的方法可以解释我提供的两个示例之间的差异,那么将不胜感激。

+0

是什么例子中的'T1'和'T2'无法编译? – NathanOliver

+0

在这个阶段,我分别用'int'和'double'测试了一个简单的for循环,调用集合函数AddElement(const T1&e1,const T2&e2)。请注意,在另一个示例(其中T1和T2是指针数组)中应用了相同的测试,并且它不会失败。 – developer10

+0

所以你同时调用'GetElement1'和'GetElement2',但只有'GetElement1'出错? – NathanOliver

回答

1

在第一Collection版本,_elements1[index]int *const&类型。这const是因为您访问const方法(实际上thisconst在这种情况下)_elements1方法,这也意味着您不允许修改_elements1[index]。当你取消_elements1[index]你会得到int&,这是_elements1[index]指向的东西。所以你可以从GetElement1返回它,它返回T1&

现在到你的第二个集合类。 GetElement1方法中的_elements1[index]方法类型为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] 
1
T1& GetElement1(int index)const { return _elements1[index]; } 

对于成员函数,编译器会将类本身(this)作为第一个参数传递给函数。由于成员函数声明之后的const修饰,GetElement1的第一个参数是常量集合,而不是收集

编辑:

#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; 
} 
+0

好吧,为什么当'T1'是一个指针数组并且我将其返回(取消引用)时,同样的错误不会显示? – developer10

+1

@ developer10 - 指针指向课堂以外的东西。指针可能是恒定的,但不是它们指向的东西。 –

+0

@BoPersson所以即使我返回值本身(例如指针,请注意“*”):'T1&GetElement1(int index)const {return * _elements1 [index]; },它在这种情况下有所不同? – developer10