模板成员函数签名冲突与非模板成员功能签名

template member function signature conflicts to non-template member function signature

本文关键字:成员 功能 冲突 函数      更新时间:2023-10-16

我最近在学习目的实施自己的矢量容器时有一个问题。

在我的矢量类中,声明了非模板成员函数和模板成员函数(插入函数(。如果发生冲突(当某些模板专业化完全匹配非模板函数签名时(,编译器给了我错误....

假设我的向量类具有2个函数,称为插入:

/* 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);
                          ^

似乎编译器试图使用模板插入函数而不是非模板插入功能。这与我的想法相矛盾。看起来,尽管我没有提供插入函数的参数列表:

myVec.insert<int*>

编译器隐式将模板插入函数与int类型进行实例化。

在cppReference的成员模板中,它还说编译器应在这种情况下使用非修辞。(请参阅成员函数模板部分(

我的环境:Ubuntu 16.04 LTS,G (Ubuntu 5.4.0-6ubuntu1〜16.04.9(5.4.0 20160609

  1. 解释为什么编译器使用模板成员函数

  2. 提供上述问题的解决方案。因此,当我确实插入(迭代器,int,int(或其他类似函数调用时,例如插入(迭代器,intered int/long,long,insted int/long(,它将调用适当的成员函数。

感谢大家的帮助。我真的很感激!

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);

33均为int类型。

现在可以解决OCERLOAD分辨率。此处的模板函数的转换为零。非template需要将int转换为size_type

零转换的人获胜。如果它们绑定,则非模板函数将在领带上获胜;但是零转换获胜。

请注意,迭代器类型是int而不是int*;这会导致身体无法编译,因为int不能被删除。