【问题标题】:Vector of doubles/ints template function双精度/整数模板函数的向量
【发布时间】:2017-06-21 02:22:57
【问题描述】:

我想概括一个函数。简单地说,我有一个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添加专业化?

标签: c++ c++11 templates vector


【解决方案1】:

通过函数模板特化分派到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&lt;T&gt;(const std::string&amp;)。实际上,如果需要更通用的解决方案,您不妨使用 Boost。但是,为了我们这里的目的,这个parse_number 很好。
  • A.S.H. 的回答很有趣,它让我可以避免专业化。有什么缺点吗?
  • @senseiwa 是的,std::stringstream 可能要慢得多。这真的取决于你的split 的效率。
  • @senseiwa,我也不确定 stringstream 对字符串中的逗号有什么影响。很确定它不起作用。
  • @senseiwa 速度没有任何问题,它只取决于您喜欢简单的直接解决方案还是创建 3 个模板声明来调度两个单行函数的解决方案。
【解决方案2】:

您可以做的一件事是使用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;
    });

【讨论】:

  • 只有在数据量很小的情况下才这样做,这样你就不会在乎它是否慢得离谱。
【解决方案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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-20
    • 2019-10-27
    • 2015-07-02
    相关资源
    最近更新 更多