首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >模板成员函数签名与非模板成员函数签名冲突

问模板成员函数签名与非模板成员函数签名冲突
EN

Stack Overflow用户
提问于 2018-02-26 04:58:05
回答 1查看 89关注 0票数 1

最近,为了学习目的,我在实现自己的向量容器时遇到了一个问题。

在中,声明一个非模板成员函数和一个具有相同名称的模板成员函数(insert函数)。如果发生冲突(当某些模板专门化与非模板函数签名完全匹配时),编译器给出了错误.

假设我的向量类有两个名为insert的函数:

代码语言:javascript
复制
/* 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中:

代码语言:javascript
复制
/* 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中:

代码语言:javascript
复制
int main()
{
    Vec<int> myVec;
    MyVec.push_back(5);
    myVec.insert( myVec.begin(), 3, 3);
}

编译器错误:

代码语言:javascript
复制
../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函数提供参数列表:

代码语言:javascript
复制
myVec.insert<int*>

编译器用int类型隐式实例化模板插入函数。

在In首选项的成员模板中,它还指出编译器在这种情况下应该使用非模板。(请参阅成员函数模板部分)

我的环境:Ubuntu16.04LTS,g++ (Ubuntu5.4.0-6 ubuntu1~16.04.9) 5.4.0 20160609

请

  1. 解释编译器为什么使用模板成员函数
  2. 提供上述问题的解决方案。这样,当我执行insert( iterator,int,int)或其他类似的函数调用(如insert( iterator,unsigned /long,unsigned /long))时,它将调用适当的成员函数。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-26 05:07:15

代码语言:javascript
复制
myVec.insert( myVec.begin(), 3, 3);

发生的第一件事是发现所有可能的重载:

代码语言:javascript
复制
iterator insert ( iterator position, size_type n, const value_type& val );
template <class InputIterator>
iterator insert (iterator position, InputIterator first, InputIterator last);

然后进行模板参数推导。在这种情况下,InputIterator=int是有效的。

代码语言:javascript
复制
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不能被取消引用。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48981686

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档