简体   繁体   English

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

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

I have some weird problem with templates. 模板有一些奇怪的问题。 When trying to pass a parameterised iterator it complains that no function can be found. 当试图传递参数化迭代器时,它抱怨没有找到任何函数。 The code snippet is here, forget about the functionality, it's using the reference to the templatized iterator what interests me 代码片段在这里,忘记了功能,它使用了对模板化迭代器的引用我感兴趣的是什么

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

If you try to compile this with g++ v4.3.2 it complains with a message saying that: 如果您尝试使用g ++ v4.3.2编译它,它会抱怨说:

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

Is there something wrong with the code I wrote or is that g++ needs more information? 我写的代码有什么问题,或者g ++需要更多信息吗?

g++ can't figure out which template overload of print_list_element it should use. g ++无法确定应该使用哪个模板重载print_list_element If you explicitly specify the template parameter it works: 如果您明确指定模板参数,它可以工作:

print_list_element<int>(it);

A better way is to write the function like this: 更好的方法是编写这样的函数:

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

This will now work for any type of iterator, not just std::list<T>::iterator . 这将适用于任何类型的迭代器,而不仅仅是std::list<T>::iterator Also, the template type will be deduced correctly from the argument. 此外,将从参数中正确推导出模板类型。

I realize that it was a contrived example, but almost always you probably didnt want to pass in list<T>::iterator to a function anyways. 我意识到这是一个人为的例子,但几乎总是你可能不想将list<T>::iterator传递给函数。 At worst, at least template on ListType so that your code would work with lists with custom allocators. 在最坏的情况下,至少是ListType上的模板,以便您的代码可以使用带有自定义分配器的列表。

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

The other responses are correct, but for completeness I'll just add that, by design, C++ can only deduce template arguments automatically in certain cases , and this isn't one of them. 其他响应是正确的,但为了完整性,我只想补充一点,按照设计,C ++只能在某些情况下自动推导出模板参数,而这不是其中之一。

When you think about it, you'll realise that automatic deduction in this case would lead to an undesirable situation. 当你考虑它时,你会发现在这种情况下自动扣除会导致不良情况。 std::list<T>::iterator is not a real type, it's just a typedef alias for a real type (eg it might be T* ) to which it is immediately translated, so the compiler would have to build some sort of "reverse index" in order to map T* back to std::list<T>::iterator for automatic deduction of T to work here. std::list<T>::iterator不是一个真正的类型,它只是一个真正类型的typedef别名(例如它可能是T* ),它立即被翻译,因此编译器必须构建某种类型的“反向索引”,以便将T*映射回std::list<T>::iterator以自动扣除T在这里工作。 But this mapping would break as soon as another class template was created that had a type member called iterator that was typedef ed to T* -- then the compiler would have two choices of what to translate T* to, and no way to choose between them. 但是,这个映射将尽快为另一个类模板创建了一种名为成员打破iterator ,这是typedef版,以T*那么编译器将有什么翻译两种选择- T*到了,没办法之间作出选择他们。 Clearly, any automatic deduction policy that breaks when an unrelated class adds a particular typedef type member is much too fragile to work. 显然,任何在不相关的类添加特定typedef类型成员时中断的自动扣除策略都太脆弱而无法工作。

暂无
暂无

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

相关问题 你如何在c ++中正确创建/传递引用参数? - How do you properly create/ pass a reference argument in c++? 如何使用 CTypes 通过引用将数组从 python 传递到 C++ function? - How do you pass an array by reference from python to a C++ function using CTypes? 如何传递对模板类型名参数的引用 - How to pass a reference to a template typename argument 如何使用 c++ 中的模板调用非成员 function,其中 typename 仅在返回中? - How do you call a non-member function with a template in c++, where the typename is only in the return? 如何将C ++引用传递给C函数的指针参数? - How do I pass a C++ reference, to a pointer argument of a C function? C++:如何将文件作为参数传递? - C++: How do you pass a file as an argument? C ++,为什么可以将右值传递给以左值引用为参数的函数 - C++, why can you pass rvalue to a function which takes lvalue reference as argument 为什么或在什么情况下,您会将参数传递给函数作为C ++中的引用(或指针)? - Why, or in what situations, would you pass an argument to a function as a reference (or pointer) in C++? 如何在使用模板时初始化数组 <typename T> C ++ - How to initialize an array when using template<typename T> C++ 将对象作为参数传递给C ++中的函数时,可以从ROOT对象访问方法吗? - Can you access methods from a ROOT object when you pass the object as an argument to a function in C++?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM