带有 std::map 的模板函数给出错误:声明为 void 的变量或字段

Posted

技术标签:

【中文标题】带有 std::map 的模板函数给出错误:声明为 void 的变量或字段【英文标题】:Template function with std::map gives error: variable or field declared 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 仅当您依赖模板参数推导时 【参考方案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;

【讨论】:

以上是关于带有 std::map 的模板函数给出错误:声明为 void 的变量或字段的主要内容,如果未能解决你的问题,请参考以下文章

c++模板和迭代器

使用 C++ 函数模板时的转换错误

模板类值的 C++ std::map

std::unordered_map 的函数指针

成员函数指针和继承

带有模板的 C++ 函数指针