【问题标题】:How do you pass a reference when using a typename as a function argument in C++?在 C++ 中使用类型名作为函数参数时如何传递引用?
【发布时间】:2009-04-15 10:55:18
【问题描述】:

我对模板有一些奇怪的问题。当尝试传递参数化迭代器时,它抱怨找不到函数。代码 sn-p 在这里,忘记功能,它使用对我感兴趣的模板化迭代器的引用

#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++ 需要更多信息?

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

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

    print_list_element<int>(it);
    

    【讨论】:

      【解决方案2】:

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

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

      这现在适用于任何类型的迭代器,而不仅仅是std::list&lt;T&gt;::iterator。此外,模板类型将从参数中正确推断出来。

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

      【讨论】:

      • +1。这甚至适用于普通数组。如果出于某种原因您真的希望它对 std::list 起作用,请查找 Boost 的 enable_if 模板。
      【解决方案3】:

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

      【讨论】:

      • 我认为'03标准的适当部分是:14.8.2.4/4。标准还说这是“非推断上下文”,而不是您上面的措辞。
      【解决方案4】:

      其他回答是正确的,但为了完整起见,我将补充一点,根据设计,C++ 只能在某些情况下自动推断模板参数,而这不是其中之一。

      细想一下,你会发现这种情况下的自动扣除会导致不良情况。 std::list&lt;T&gt;::iterator 不是真实类型,它只是真实类型的 typedef 别名(例如,它可能是 T*),它会立即转换为,因此编译器必须构建某种“反向索引”为了将T* 映射回std::list&lt;T&gt;::iterator 以自动扣除T 到这里工作。但是,一旦创建了另一个类模板,该类模板的类型成员名为iteratortypedefed 到T*,此映射就会中断——然后编译器将有两种选择将T* 转换为的内容,并且无法在它们之间进行选择。显然,当不相关的类添加特定的typedef 类型成员时中断的任何自动推导策略都太脆弱而无法工作。

      【讨论】:

        猜你喜欢
        • 2015-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-30
        • 1970-01-01
        • 1970-01-01
        • 2020-11-29
        • 2021-11-25
        相关资源
        最近更新 更多