是否可以使用C ++模板函数来获取T类型的任何集合?

时间:2015-04-02 03:46:54

标签: c++ templates iterator

我想知道是否有办法创建一个模板函数,该函数引用特定类型的任何集合。例如:

class Bob
{
  public:
  int age;
  int height;
}

template<class T>
void functionWhichIteratesOverBobs(T &bobs)
{
    int totalAge = 0;
    for(auto &bob: bobs)
    {
         totalAge += bob.age;
    }
}

基本上有一种方法可以在模板函数的定义中要求T有一个begin()和end()函数,它将迭代器返回给T.

我已经看到了以下问题,但这需要一个起点和终点的功能,即

std::vector<Bob> bobs;
functionWhichIteratesOverBobs(bob.begin(), bob.end());

当我想要的是:

std::vector<Bob> bobs;
functionWhichIteratesOverBobs(bobs);

Function that takes an STL iterator over ANY container of a elements of a specific type

3 个答案:

答案 0 :(得分:1)

如果您希望保持过载设置未受污染,请使用表达式SFINAE,如下所示:

template<class T>
void functionWhichIteratesOverBobs(T &bobs)
  -> decltype(std::begin(bobs), std::end(bobs), void()) {
    // [..Range based for over bobs..] 
}

请记住,如果给出错误的参数,您显示的函数模板不会在没有错误的情况下实例化,所以这当前是多余的 - 直到您开始重载functionWhichIteratesOverBobs

答案 1 :(得分:0)

C ++概念Container的成员类型value_type是所包含元素的类型,因此您可以像使用迭代器一样使用SFINAE - 它甚至更简单,因为您不需要使用iterator_traits

template<class T>
auto functionWhichIteratesOverBobs(T &bobs)
    -> std::enable_if_t<std::is_same_v<typename T::value_type, Bob>>
{
    // ...
}

请注意,这不适用于原始数组;如果您希望这些工作,您可以使用decltype(std::begin(bobs))iterator_traits

template<class T>
auto functionWhichIteratesOverBobs(T &bobs) -> std::enable_if_t<std::is_same_v<
    typename std::iterator_traits<decltype(std::begin(bobs))>::value_type, Bob>>
{
    // ...
}

答案 2 :(得分:0)

是。这是可能的。

作为Ed S. comment,只需使用您在问题中编写的相同功能。如果bobs没有begin()end(),编译器会通过生成错误通知您。
Demo