接受stl_container_type <string> :: iterator的模板化参数

Chr*_*lin 7 c++ templates iterator

我有一个函数,其中我有保持的字符串(例如一个容器vector<string>,set<string>,list<string>给定的开始迭代和结束迭代器),并且,经过迭代范围处理所述字符串.

目前该函数声明如下:

template< typename ContainerIter>
void ProcessStrings(ContainerIter begin, ContainerIter end);
Run Code Online (Sandbox Code Playgroud)

现在,这将接受任何符合实现operator*,前缀operator++和函数体中其他调用的隐式接口的类型.

我真正想做的是有一个像下面那样明确限制输入量的定义(伪代码警告):

template< typename Container<string>::iterator>
void ProcessStrings(Container<string>::iterator begin, Container<string>::iterator end);
Run Code Online (Sandbox Code Playgroud)

所以我可以这样使用它:

vector<string> str_vec;
list<string> str_list;
set<SomeOtherClass> so_set;

ProcessStrings(str_vec.begin(), str_vec.end());  // OK
ProcessStrings(str_list.begin(), str_list.end());  //OK
ProcessStrings(so_set.begin(), so_set.end());  // Error
Run Code Online (Sandbox Code Playgroud)

本质上,我想要做的是限制函数规范,使函数的用户明白它接受的内容,如果代码编译失败,他们会得到一条消息,他们使用了错误的参数类型而不是XXX类无法找到XXX函数的函数体.

Mik*_*our 4

您可以使用模板模板参数来接近这一点:

template<template<class> class CONTAINER>
void ProcessStrings(CONTAINER<string>&);
Run Code Online (Sandbox Code Playgroud)

这将处理整个容器,如果它不包含字符串,则会给出编译错误。

ProcessStrings(str_vec); // OK
ProcessStrings(so_set); // Error
Run Code Online (Sandbox Code Playgroud)

如果你想使用迭代器范围,那么我能管理的最好的就是

template<template<class> class CONTAINER>
void ProcessStrings(typename CONTAINER<string>::iterator, 
                    typename CONTAINER<string>::iterator);
Run Code Online (Sandbox Code Playgroud)

不幸的是,类型推断不适用于函数参数,因此您必须显式给出模板参数:

ProcessStrings<vector>(str_vec.begin(), str_vec.end()); // OK
ProcessStrings<set>(so_set.begin(), so_set.end()); // Error
Run Code Online (Sandbox Code Playgroud)

有人可以对此进行改进吗?