繁体   English   中英

在C ++中使用typename作为函数参数时,如何传递引用?

[英]How do you pass a reference when using a typename as a function argument in C++?

模板有一些奇怪的问题。 当试图传递参数化迭代器时,它抱怨没有找到任何函数。 代码片段在这里,忘记了功能,它使用了对模板化迭代器的引用我感兴趣的是什么

#include <list>
#include <iostream>

template<typename T>
void print_list_element(typename std::list<T>::iterator& it){
    std::cout << *it << std::endl;
}

int main() {
    std::list<int> theList;
    theList.push_back(1);

    std::list<int>::iterator it = theList.begin();
    print_list_element(it);

    return 0;
}

如果您尝试使用g ++ v4.3.2编译它,它会抱怨说:

main.cpp:14: error: no matching function for call to 'print_list_element(std::_List_iterator<int>&)'

我写的代码有什么问题,或者g ++需要更多信息吗?

g ++无法确定应该使用哪个模板重载print_list_element 如果您明确指定模板参数,它可以工作:

print_list_element<int>(it);

更好的方法是编写这样的函数:

template<typename Iter>
void print_element(Iter it){
    std::cout << *it << std::endl;
}

这将适用于任何类型的迭代器,而不仅仅是std::list<T>::iterator 此外,将从参数中正确推导出模板类型。

我意识到这是一个人为的例子,但几乎总是你可能不想将list<T>::iterator传递给函数。 在最坏的情况下,至少是ListType上的模板,以便您的代码可以使用带有自定义分配器的列表。

这是非法的,因为std :: list <T> :: iterator不是标准所称的适当的推导上下文

其他响应是正确的,但为了完整性,我只想补充一点,按照设计,C ++只能在某些情况下自动推导出模板参数,而这不是其中之一。

当你考虑它时,你会发现在这种情况下自动扣除会导致不良情况。 std::list<T>::iterator不是一个真正的类型,它只是一个真正类型的typedef别名(例如它可能是T* ),它立即被翻译,因此编译器必须构建某种类型的“反向索引”,以便将T*映射回std::list<T>::iterator以自动扣除T在这里工作。 但是,这个映射将尽快为另一个类模板创建了一种名为成员打破iterator ,这是typedef版,以T*那么编译器将有什么翻译两种选择- T*到了,没办法之间作出选择他们。 显然,任何在不相关的类添加特定typedef类型成员时中断的自动扣除策略都太脆弱而无法工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM