自从我发现boost::lexical_cast
以来,所有转换都是轻而易举的。直到尝试将元组元素转换为字符串。与Int2String
或Double2String
一样,我希望从任意数量的元素元组生成单个字符串
由于转换主题具有任意(但编译已知的时间)维度,因此在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);
我收到编译错误
错误C2893:无法专门化函数模板'enable_if,void&gt; :: type boost :: fusion :: for_each(const Sequence&amp;,const F&amp;)'
答案 0 :(得分:3)
由于这个问题被标记为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,请用lexical_cast替换to_string。
上的实时输出答案 1 :(得分:3)
很抱歉,但是我太懒了,不能详细说明你犯错误的地方,但是这里有一个使用fusion和C ++ 14多态lambda的解决方案:
#include <tuple>
#include <string>
#include <iostream>
#include <boost/lexical_cast.hpp>
#include <boost/fusion/adapted/std_tuple.hpp> // you're missing this huh? it's needed to use fusion with std::tuple
#include <boost/fusion/algorithm/iteration/for_each.hpp>
int main() {
using namespace std;
using namespace boost::fusion;
string result;
for_each(make_tuple(1, 'a', 2.2), [&result](auto &s) {
result += boost::lexical_cast<string>(s) + ' ';
});
cout << result << endl;
}