将模板函数作为参数传递给C++; 加速C++,问题8~5/p>

将模板函数作为参数传递给C++; 加速C++,问题8~5/p>,c++,templates,stl,C++,Templates,Stl,我已经编写了一个小程序,它检查字符串输入的行,并计算单词在给定行上出现的次数。以下代码实现了这一点: #include <map> #include <iostream> #include <string> #include <vector> #include <list> #include <cctype> #include <iterator> using std::vector; usin

我已经编写了一个小程序,它检查字符串输入的行,并计算单词在给定行上出现的次数。以下代码实现了这一点:

#include <map>
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <cctype>
#include <iterator>

using std::vector;         using std::string;
using std::cin;            using std::cout;
using std::endl;           using std::getline;
using std::istream;        using std::string;
using std::list;           using std::map;
using std::isspace;        using std::ostream_iterator;
using std::allocator;

inline void keep_window_open()
{
    cin.clear();
    cout << "Please enter EOF to exit\n";
    char ch;
    cin >> ch;
    return;
}

template <class Out>
void split(const string& s, Out os)
{
    vector<string> ret;
    typedef string::size_type string_size;
    string_size i = 0;

    // invariant: we have processed characters `['original value of `i', `i)'
    while (i != s.size()) {
        // ignore leading blanks
        // invariant: characters in range `['original `i', current `i)' are all spaces
        while (i != s.size() && isspace(s[i]))
            ++i;

        // find end of next word
        string_size j = i;
        // invariant: none of the characters in range `['original `j', current `j)' is a space
        while (j != s.size() && !isspace(s[j]))
            ++j;

        // if we found some nonwhitespace characters
        if (i != j) {
            // copy from `s' starting at `i' and taking `j' `\-' `i' chars
            *os++ = (s.substr(i, j - i));
            i = j;
        }
    }
}


// find all the lines that refer to each word in the input
map<string, vector<int> > xref(istream& in)     // works
// now try to pass the template function as an argument to function - what do i put for templated type?
//map<string, vector<int> > xref(istream& in, void find_words(vector<string, typedef Out) = split)      #LINE 1#
{
    string line;
    int line_number = 0;
    map<string, vector<int> > ret;

    // read the next line
    while (getline(in, line)) {
        ++line_number;

        // break the input line into words
        vector<string> words;   // works            // #LINE 2#
        split(line, back_inserter(words));          // #LINE 3#
        //find_words(line, back_inserter(words));   // #LINE 4# attempting to use find_words as an argument to function

        // remember that each word occurs on the current line
        for (vector<string>::const_iterator it = words.begin();
             it != words.end(); ++it)
            ret[*it].push_back(line_number);
    }
    return ret;
}

int main()
{
    cout << endl << "Enter lines of text, followed by EOF (^Z):" << endl;

    // call `xref' using `split' by default
    map<string, vector<int> > ret = xref(cin);

    // write the results
    for (map<string, vector<int> >::const_iterator it = ret.begin();
         it != ret.end(); ++it) {
        // write the word
        cout << it->first << " occurs on line(s): ";

        // followed by one or more line numbers
        vector<int>::const_iterator line_it = it->second.begin();
        cout << *line_it;   // write the first line number

        ++line_it;
        // write the rest of the line numbers, if any
        while (line_it != it->second.end()) {
            cout << ", " << *line_it;
            ++line_it;
        }
        // write a new line to separate each word from the next
        cout << endl;
    }
    keep_window_open();
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用std::vector;使用std::string;
使用std::cin;使用std::cout;
使用std::endl;使用std::getline;
使用std::istream;使用std::string;
使用std::list;使用std::map;
使用std::isspace;使用std::ostream_迭代器;
使用std::分配器;
内联无效保持窗口打开()
{
cin.clear();
cout>ch;
返回;
}
模板
无效拆分(常量字符串和s,输出操作系统)
{
向量ret;
typedef string::size\u type string\u size;
字符串大小i=0;
//不变量:我们已经处理了字符“['i'的原始值,'i]”
而(i!=s.size()){
//忽略前导空格
//不变:范围“['original'i',current'i”中的字符都是空格
而(i!=s.size()&&isspace(s[i]))
++一,;
//找到下一个单词的结尾
串_尺寸j=i;
//不变:范围“['original'j',current'j]”中的字符都不是空格
而(j!=s.size()&&!isspace(s[j]))
++j;
//如果我们找到一些非空白字符
如果(i!=j){
//从's'复制,从'i'开始,取'j''-'i'字符
*os++=(s.substr(i,j-i));
i=j;
}
}
}
//查找输入中与每个单词相关的所有行
映射外部参照(istream&in)//工作
//现在尝试将模板函数作为参数传递给函数-对于模板化类型,我应该放置什么?
//映射外部参照(istream&in,void find_words(vector),或者编译器能否从模板函数在主体中的使用方式推断类型

这个问题的答案是:不

您需要将“typedef Out”更改为back_inserter返回的类型,并且需要为“=split”提供相同的类型

Buff-IxEnter返回的类型是由标准指定的,因此您应该能够在C++ LIB引用中找到它。 您也可以尝试将外部参照函数转换为以函数模板作为参数(及其类型)的模板。不过,我从未尝试过类似的操作,但函数除外,因此我不知道它会带来多大的成功。这可能是您想要的,也可能不是


如果您使用的是c++0x,您将有更多的选项,这些选项可能更符合您的需要。

以下是一个解决方法。 可以使用带有静态函数的类

struct split
{
  template <class Out>
  static apply(const string& s, Out os) { 
    // include the body of your split function or call to an existing function
  }

};
结构拆分
{
模板
静态应用(常量字符串&s,输出操作系统){
//包括拆分函数的主体或对现有函数的调用
}
};
现在,将外部参照设置为通用

template <typename FIND_WORDS>
map<string, vector<int> > xref(istream& in, FIND_WORDS find_words = split()) 
{

  // replace #2 and #3 by
  find_words.apply(line, back_inserter(words));

}; 
模板
映射外部参照(istream&in,FIND_WORDS FIND_WORDS=split())
{
//将#2和#3替换为
查找单词。应用(行,后插入器(单词));
}; 

请尝试发布最小的示例代码。此外,C++中没有“模板函数”。它是一个“函数模板”。我认为使用名称空间STD的简单<代码>;将是足够的:并发布不起作用的代码-不要让我们自己编辑。我本来打算把你的代码编辑到基本问题上,但我真的不知道你问的问题是什么,或者如何转换代码以说明问题。要点。我认为发布一个完整的、有效的程序是最好的了解我正在尝试做的事情。谢谢,我会看看我能做些什么来挖掘类型。我确实尝试过,但我甚至不能确定我是否能将函数模板作为参数传递,谷歌搜索结果也不多。谢谢你的回复。我仍然收到一个错误“无法推断‘查找单词’的模板参数”当我做这些更改时。我会继续努力,看看是否能让它工作。在需要的地方添加tympename,或者只是用find_words替换find_words::apply。applyI能够让它工作,但没有使用默认参数。我必须创建一个拆分“s”,然后调用xref(cin,s)。它允许外部参照调用静态函数s.apply()。这是使用外部参照(istream&in,FIND_WORDS s)。我尝试将外部参照(cin)与外部参照(istream&in,FIND_WORDS s s=split)一起使用,但无法编译-表示没有与参数列表匹配的外部参照实例。