为map <t1,t2>迭代器创建模板函数

时间:2017-10-17 00:18:30

标签: c++ templates generics template-function

所以我试图制作4个模板函数来执行以下操作:总结一个通用容器,求和一个映射,求和泛型容器迭代器,以及求和泛型映射迭代器。我已经成功完成了前三个,但我无法弄清楚总和映射迭代器。这是我的代码:

Sum.hpp

#ifndef SUM_HPP
#define SUM_HPP

#include <iostream>
#include <map>
#include <string>
using namespace std;

//Sum Generic Container
template <typename T>
double Sum(const T& cont) {
    double sum = 0; 

    typename T::const_iterator iter = cont.begin();
    for (iter; iter != cont.end(); iter++) {
        sum += *iter;
    }

return sum;
}

//Sum Generic Map
template <typename T1, typename T2>
double Sum(const map<T1, T2>& mp) {
    double sum = 0;

    typename map<T1,T2>::const_iterator iter = mp.begin();
    for (iter; iter != mp.end(); iter++) {
        sum += iter->second;
    }

    return sum;
}

//Sum Generic Container Iterators
template <typename T>
double Sum(T& begin, const T& end) {
    double sum = 0;

    for (begin; begin != end; begin++) {
        sum += *begin;
    }

    return sum;
}

//Sum Generic Map Iterators
template <typename T1, typename T2>
double Sum(map<T1, T2>::iterator& begin, map<T1, T2>::iterator& end) {
    double sum = 0;

    for (begin; begin != end; begin++) {
        sum += begin->second;
    }

    return sum;
}


#endif  

Test.cpp的:

#include "Sum.hpp"
#include <iostream>
#include <map>
using namespace std;

int main() {
    //Map
    cout << "map" << endl;
    map<string, double> mp;

    mp["weight"] = 5.5;
    mp["height"] = 6.7;
    mp["length"] = 8.4;

    map<string, double>::iterator mp_iter_begin = mp.begin();
    map<string, double>::iterator mp_iter_end = mp.end();
    cout << Sum(mp_iter_begin, mp_iter_end) << endl;

    return 0;
}

当我运行Sum()函数时,它尝试调用Sum Generic Container Iterators函数,如果我注释掉Sum Generic Container Iterators函数,我得到一个&#34;没有重载函数的实例&#34;错误。谁能发现我做错了什么?

2 个答案:

答案 0 :(得分:2)

这属于non-deduced contexts

  

1)嵌套名称说明符(范围解析运算符左侧的所有内容::)使用qualified-id指定的类型:

这意味着对于map<T1, T2>::iterator,无法推断出模板参数T1T2

您可以通过SFINAE解决问题,例如

//Sum Generic Container Iterators
template <typename T>
auto Sum(T begin, T end) -> remove_reference_t<decltype(*begin += *begin)> {

    remove_reference_t<decltype(*begin)> sum = 0;

    for (; begin != end; begin++) {
        sum += *begin;
    }

    return sum;
}

//Sum Generic Map Iterators
template <typename T>
auto Sum(T begin, T end) -> remove_reference_t<decltype(begin->second += begin->second)> {

    remove_reference_t<decltype(begin->second)> sum = 0;

    for (; begin != end; begin++) {
        sum += begin->second;
    }

    return sum;
}

LIVE

答案 1 :(得分:0)

我想出了如何以我想要的方式进行专业化:

//Sum Generic Container Iterators
template <typename T>
double Sum(T& begin, const T& end) {
    double sum = 0;

    for (begin; begin != end; begin++) {
        sum += *begin;
    }

    return sum;
}

//Sum Map<string, double> Iterators
template <>
double Sum(map<string, double>::iterator& begin, const map<string, double>::iterator& end) {
    double sum = 0;

    for (begin; begin != end; begin++) {
        sum += begin->second;
    }

    return sum;
}

请注意确保通用容器迭代器和映射迭代器函数具有匹配参数的重要性(两个参数都是引用,第二个参数是两个模板函数的const)或者map<string,double>的特化不起作用。