【问题标题】:Template function with std::map gives error: variable or field declared void带有 std::map 的模板函数给出错误:声明为 void 的变量或字段
【发布时间】:2018-04-19 12:05:53
【问题描述】:

试图创建模板函数什么 couts std::map 元素,得到这个错误。我知道地图有四个模板参数,但两个有默认值,无法理解我必须做什么。

template<typename key, typename val> void arr_out (std::map<key, val>::iterator begin, std::map<key, val>::iterator end)
{
    std::cout << "map: " << std::endl;
    while(begin != end)
    {
        std::cout << (*begin).first << ": " << (*begin).second << std::endl ;
        begin++;
    }
    std::cout << std::endl;
}
  • 错误:变量或字段“arr_out”声明为无效
  • 错误:在“开始”之前应为“)”
  • 错误:在“开始”之前应为“)”

【问题讨论】:

  • 在两个位置的std::map&lt;key,val&gt;:: 之前添加一个typename
  • @AndyG 还有错误even if you do that
  • @Borgleader 仅当您依赖模板参数推导时

标签: c++


【解决方案1】:

您应该在每个模板函数参数之前添加 typename 关键字:

template<typename key, typename val> 
void arr_out (typename std::map<key, val>::iterator begin, 
              typename std::map<key, val>::iterator end)

【讨论】:

    【解决方案2】:

    在迭代器前加上typename,表示它是模板的嵌套值类型。

    template<typename key, typename val> 
    void arr_out(typename std::map<key, val>::iterator begin, typename std::map<key, val>::iterator end)
    {
        std::cout << "map: " << std::endl;
        while(begin != end)
        {
            std::cout << (*begin).first << ": " << (*begin).second << std::endl ;
            begin++;
        }
        std::cout << std::endl;
    }
    

    【讨论】:

      【解决方案3】:

      要使代码有效,您必须添加typename

      template<typename key, typename val>
      void arr_out (typename std::map<key, val>::iterator begin,
                    typename std::map<key, val>::iterator end);
      

      因为参数是不可推导的,所以称之为:

      std::map<Key, Value> m;
      arr_out<Key, Value>(m.begin(), m.end());
      

      简化呼叫站点的替代方法是:

      template <typename It>
      void arr_out (It begin, It end);
      

      或与一些 SFINAE:

      template <typename It>
      auto arr_out (It begin, It end)
      -> decltype(void(std::cout << (*begin).first << (*begin).second));
      

      【讨论】:

      • 感谢您提供 typename It 的提示!我不得不猜测。
      【解决方案4】:

      模板推演规则不允许你从std::map&lt;key, val&gt;::iterator推断keyval

      其他答案告诉你如何更正定义,但你在使用时必须指定类型参数。

      int main()
      {
          std::map<int, std::string> m;
          // arr_out(m.begin(), m.end()); // errors relating to template argument deduction
          arr_out<int, std::string>(m.begin(), m.end()); // Ok
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多