如何将重载函数作为模板化函数参数传递?

时间:2016-09-10 21:14:29

标签: c++ templates c++11

所以我要做的是编写一个通用函数,它接受一个字符串,将其拆分为一个类型化的向量。这是我的代码,问题是它无法将stod函数类型解析为我指定的泛型函数包装器。

#include <string>
#include <sstream>
#include <vector>
#include <iostream>
#include <functional>

using std::vector;
using std::string;
using std::function;
using std::stringstream;


int main(int argc, const char * argv[]) {
    SplitStringToTypedVector("1.23 3.45 5.21", ' ', static_cast<double (*)(const string&, size_t*)>(&std::stod)); 

    system("pause");
    return 0;
}

template <typename T>
vector<T> SplitStringToTypedVector(const string &s, char delim, function<T (*)(const string&, size_t*)> conversionFunc) {
    vector<T> elements;
    stringstream stream;
    string element;
    while (getline(stream, element, delim)) {
        elements.push_back(conversionFunc(element));
    }
    return elements;
}

2 个答案:

答案 0 :(得分:0)

使用lambda来解析函数类型可能更干净,而不是担心消除stod的重载歧义:

#include <string>
#include <sstream>
#include <vector>
#include <iostream>
#include <functional>

using std::vector;
using std::string;
using std::function;
using std::stringstream;

template <class Func>
auto SplitStringToTypedVector(const string &s, 
                                   char delim, 
                                   Func&& conversionFunc) {
  using result_type = decltype(conversionFunc(s));
    vector<result_type> elements;
    stringstream stream;
    string element;
    while (getline(stream, element, delim)) {
        elements.push_back(conversionFunc(element));
    }
    return elements;
}

int main(int argc, const char * argv[]) {
    SplitStringToTypedVector("1.23 3.45 5.21", 
                             ' ', 
                             [](std::string const& s) { return std::stod(s); }); 

    system("pause");
    return 0;
}

答案 1 :(得分:0)

关于代码的一些观点。

(1)您在$(function(){ $.ajax({ type: "GET", url: '@Url.Action("GetVotings","Chart")', }).done(function (votings) { var labelsArray = []; var dataArray = []; $.each(votings, function (index, data) { labelsArray.push(data.Name); dataArray.push(data.Voice); }); renderChart(labelsArray, dataArray); }); }); 之前,在其定义之前致电SplitStringToTypedVector()。那很糟糕。您应该main()main()SplitStringToTypedVector()之前添加SplitStringToTypedVector()的原型作为<{1}}

(2)使用main()你必须避免std::function;所以

(*)

而不是

function<T(const string&, size_t*)> conversionFunc

(3)声明你的函数function<T(*)(const string&, size_t*)> conversionFunc 接收2个参数。我知道conversionFunc()的第二个参数有一个默认值,但我不认为std::tod能够知道它。因此使用参数

调用SplitStringToTypedVector()是错误的
conversionFunc()

你必须用两个

来调用它
elements.push_back(conversionFunc(element));

(4)我不知道如何强制识别elements.push_back(conversionFunc(element)); 类型T(我的极限,我想);但你可以明确它

SplitStringToTypedVector()