最近,为了学习目的,我在实现自己的向量容器时遇到了一个问题。
在中,声明一个非模板成员函数和一个具有相同名称的模板成员函数(insert函数)。如果发生冲突(当某些模板专门化与非模板函数签名完全匹配时),编译器给出了错误.
假设我的向量类有两个名为insert的函数:
/* Vec.h */
template <class T> class Vec {
public:
iterator insert ( iterator position, size_type n, const value_type& val );
template <class InputIterator>
iterator insert (iterator position, InputIterator first, InputIterator last);
}
#include "Vec.hpp"在Vec.hpp中:
/* Vec.hpp */
template <class T>
typename Vec<T>::iterator Vec<T>::insert( iterator position,
size_type n,
const value_type& val)
{
/* Implementation */
}
template <class T> template <class InputIterator>
typename Vec<T>::iterator Vec<T>::insert( iterator position,
InputIterator first,
InputIterator last )
{
/* Some code ... */
/* Copy the element */
while( first != last )
{
new ( position + idx ) T(*first);
++idx;
++first;
}
/* Some other code ... */
}在main.cpp中:
int main()
{
Vec<int> myVec;
MyVec.push_back(5);
myVec.insert( myVec.begin(), 3, 3);
}编译器错误:
../Vec.hpp: In instantiation of ‘T* Vec<T>::insert(Vec<T>::iterator, InputIterator, InputIterator) [with InputIterator = int; T = int;
Vec<T>::iterator = int*]’:
../main.cpp:128:45: required from here
../Vec.hpp:306:30: error: invalid type argument of unary ‘*’ (have ‘int’)
new ( position + idx ) T(*first);
^编译器似乎试图使用模板插入函数而不是非模板函数。这与我的想法相矛盾。看起来,虽然我没有为insert函数提供参数列表:
myVec.insert<int*>编译器用int类型隐式实例化模板插入函数。
在In首选项的成员模板中,它还指出编译器在这种情况下应该使用非模板。(请参阅成员函数模板部分)
我的环境:Ubuntu16.04LTS,g++ (Ubuntu5.4.0-6 ubuntu1~16.04.9) 5.4.0 20160609
请
谢谢大家的帮助。我真的很感激!!
发布于 2018-02-26 05:07:15
myVec.insert( myVec.begin(), 3, 3);发生的第一件事是发现所有可能的重载:
iterator insert ( iterator position, size_type n, const value_type& val );
template <class InputIterator>
iterator insert (iterator position, InputIterator first, InputIterator last);然后进行模板参数推导。在这种情况下,InputIterator=int是有效的。
iterator insert ( iterator position, size_type n, const int& val );
template <>
iterator insert (iterator position, int first, int last);因为3和3都是int类型的。
现在它执行ocerload解析。这里的模板函数有零转换。非模板需要将int转换为size_type。
零转换的人赢了。如果他们打成平手,那么非模板函数在领带上就赢了;但是零转换赢了。
注意,迭代器类型是int而不是int*;这会导致主体无法编译,因为int不能被取消引用。
https://stackoverflow.com/questions/48981686
复制相似问题