c++ - 将元组转换为字符串

标签 c++ c++11

自从我发现 boost::lexical_cast 以来,所有的转换都变得轻而易举。直到尝试将元组元素转换为字符串。像 Int2StringDouble2String 我想要一种从任意数量元素的元组生成单个字符串的方法

由于转换的主题具有任意(但编译时间已知)维度,在 some research 之后我调查了boost::fusion并找到了这个解决方案:

#include <string>
#include <boost/lexical_cast.hpp>
#include <boost/noncopyable.hpp>
#include <boost/fusion/include/for_each.hpp>

template <class Sequence>
std::string StringFromSequence(const Sequence &seq) 
{
    std::string result;
    boost::fusion::for_each(seq, toString(result));
    return result;
}

其中 toString 是一个仿函数,将词法转换应用于被调用的对象:

struct toString: boost::noncopyable 
{
    explicit toString(std::string& res) : result(res)
    {
    }
    template <class T>
    void operator()(const T& v) 
    {
        result += boost::lexical_cast<std::string>(v);
    }
private:
    std::string &result;
};

虽然尝试使用它时

std::tuple<int, char, double> tup{ 1, 'a', 2.2 };
toString(tup);

编译出错

error C2893: Failed to specialize function template 'enable_if, void>::type boost::fusion::for_each(const Sequence &,const F &)'

  1. 有人可以发现并改正错误吗?
  2. 是否有任何替代方案(也许免费提升)? (这需要编译时递归,我希望能避免所有这些样板代码)

最佳答案

由于这个问题被标记为 C++11,所以这是我的看法:

#include <iostream>
#include <string>
#include <tuple>

template<typename T, T...>
struct integer_sequence { };

template<std::size_t N, std::size_t... I>
struct gen_indices : gen_indices<(N - 1), (N - 1), I...> { };
template<std::size_t... I>
struct gen_indices<0, I...> : integer_sequence<std::size_t, I...> { };

template<typename H>
std::string& to_string_impl(std::string& s, H&& h)
{
  using std::to_string;
  s += to_string(std::forward<H>(h));
  return s;
}

template<typename H, typename... T>
std::string& to_string_impl(std::string& s, H&& h, T&&... t)
{
  using std::to_string;
  s += to_string(std::forward<H>(h));
  return to_string_impl(s, std::forward<T>(t)...);
}

template<typename... T, std::size_t... I>
std::string to_string(const std::tuple<T...>& tup, integer_sequence<std::size_t, I...>)
{
  std::string result;
  int ctx[] = { (to_string_impl(result, std::get<I>(tup)...), 0), 0 };
  (void)ctx;
  return result;
}

template<typename... T>
std::string to_string(const std::tuple<T...>& tup)
{
  return to_string(tup, gen_indices<sizeof...(T)>{});
}

int main(int argc, char** argv)
{
  std::tuple<int, double, float> tup(1, 2.1, 3.2);
  std::cout << to_string(tup) << std::endl;
}

如果你想坚持使用 boost::lexical_cast,请将 to_string 替换为 lexical_cast。

ideone 上的实时输出

关于c++ - 将元组转换为字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23436406/

相关文章:

count_if 算法中的 C++ 编译器错误

c++ - 给定种子和偏移量生成下一个伪随机值

c++ - 类成员是一个类型未知的派生对象

c++ - Linux 上的 FreeImage 返回 -1 格式

c++ - 回归虚无?

c++11 - 链接器找不到符号,但是它们在那里?

c# - 开销 - 从 C# 调用 C++ 函数

c++ - Lambda 捕获 constexpr 对象

c++ - 带有可变参数模板的标记分派(dispatch),c++11

c++ - 使用初始化列表初始化成员数组的正确方法是什么?