双精度/整数向量模板函数

6
我有一个函数想要泛化。简单来说,我有一个std::string s被处理成一个生成std::vector<std::string>的解析器(它是一个列表,如"1, 2, 3"),并且该函数应该返回一个std::vector<T>,其中T受限于doubleint
该向量应包含转换后的值。
我卡在了std::transform的最后一个参数上,因为它应该在std::stodstd::stoi之间切换。我正在寻找的解决方案是使用模板元编程魔法,而不是使用if (std::is_same<T,int>::value)
有提示吗?
template <class T>
auto get_vector(std::string s) -> std::vector<T>
{
    std::vector<T> v;

    auto tmp = split(s);

    std::transform(tmp.begin(), tmp.end(), std::back_inserter(v), ??);

    return v;
}

double 添加一个专业化? - alain
3个回答

7

通过函数模板特化,将调度转到std::stoistd::stod

template <typename T>
auto parse_number(std::string const& s) -> T;

template <>
auto parse_number<int>(std::string const& s) -> int
{
    return std::stoi(s);
}

template <>
auto parse_number<double>(std::string const& s) -> double
{ 
    return std::stod(s);
}

template <class T>
auto get_vector(std::string const& s) -> std::vector<T>
{
    std::vector<T> v;
    auto tmp = split(s);
    std::transform(tmp.begin(), tmp.end(), std::back_inserter(v), &parse_number<T>);
    return v;
}

这就是答案。简而言之,OP需要调用some_lexical_caster<T>(const std::string&)。实际上,如果需要更一般的解决方案,您也可以使用Boost。但是,对于我们在这里的目的,这个parse_number就足够了。 - Lightness Races in Orbit
1
A.S.H.的答案很有趣,它让我避免了专业化。是否存在任何缺点? - senseiwa
@ senseiwa 是的,std::stringstream 可能会慢得多。这确实取决于您的 split 的效率。 - yuri kilochek
@ senseiwa,我也不确定stringstream会如何处理您字符串中的逗号。相当确定它不起作用。 - yuri kilochek
@senseiwa,速度方面没有任何问题,只要你喜欢简单和直接的解决方案,或者喜欢创建3个模板声明以分派两个单行函数的解决方案。 - A.S.H

5

您可以利用 stringstreamlambda 来让 stringstream 为您进行转换。类似这样:

std::transform(tmp.begin(), tmp.end(), std::back_inserter(v),
    [](const std::string& elem) -> T
    {
        std::stringstream ss(elem);
        T value;
        ss >> value;
        return value;
    });

4
只有当数据量非常小且速度极慢也无所谓时才应这样做。 - Ben Voigt

3
使用 istream_iterator:
template <class T>
auto get_vector(std::string s) -> std::vector<T> {
    std::vector<T> v;
    std::istringstream iss(s);
    std::copy(std::istream_iterator<T>(iss), std::istream_iterator<T>(), std::back_inserter(v));
    return v;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接