gpt4 book ai didi

c++ - 如何将各种类型的 vector 转换为 std::string?

转载 作者:行者123 更新时间:2023-12-01 14:14:54 24 4
gpt4 key购买 nike

我从 来到 C++和 其中有将数据类型转换为字符串的内置方法。

例如,在 Haskell 中有一个多态函数 show .

我有兴趣在 C++ 中创建一些可以执行类似操作的模板函数。

例如,我们可以转换 vector<int>到像这样的字符串。

string toString(vector<int> v)
{
ostringstream o;
for (int elem: v)
o << elem << " ";
return o.str()
}

这会放置 int 的字符串表示形式都在一条线上。现在,如果我想转换 vector<vector<int> > 怎么办?以这种方式。

string toString(vector<vector<int> > v)
{
ostringstream o;
for (auto elem : v)
{
o << toString(elem) << "\n";
}
}

我的问题是:如果我想创建一个多态的 toString 怎么办?适用于 vector<class A>vector<vector<class A> ?我该怎么做?

我需要添加一些功能来转换类型 class Astd::string : 我是否只提供至少一项 toString 的特化?对于那种类型?模板机制是否解决了所有这些问题?

或者是否已经有代码可以做到这一点?

最佳答案

What if I wanted to create a polymorphic toString that works with vector<class A> and vector<vector<class A>? How would I go about this?

是的,这是可能的 , 通过组合 if constexpr 特征和递归函数模板(即将 toString 作为递归函数模板)。

在进入通用函数模板之前,您的 class A需要实现operator<<重载所以 std::ostringstream::operator<< 可以利用它。例如,让我们考虑

struct A
{
char mChar;
// provide a overload for operator<< for the class!
friend std::ostream& operator<<(std::ostream& out, const A& obj) /* noexcept */ {
return out << obj.mChar;
}
};

现在 toString函数看起来像下面这样:

#include <type_traits> // std::is_floating_point_v, std::is_integral_v, std::is_same_v
// std::remove_const_t, std::remove_reference_t

template<typename Type>
inline static constexpr bool isAllowedType = std::is_floating_point_v<Type>
|| std::is_integral_v<Type>
|| std::is_same_v<A, Type>;
//^^^^^^^^^^^^^^^^^^^ --> struct A has been added to the
// allowed types(i.e types who has operator<< given)

template<typename Vector>
std::string toString(const Vector& vec) /* noexcept */
{
std::ostringstream stream;
// value type of the passed `std::vector<Type>`
using ValueType = std::remove_const_t<
std::remove_reference_t<decltype(*vec.cbegin())>
>;
// if it is allowed type do concatenation!
if constexpr (isAllowedType<ValueType>)
{
for (const ValueType& elem : vec)
stream << elem << " ";

stream << '\n';
return stream.str();
}
else
{
// otherwise do the recursive call to toString
// for each element of passed vec
std::string result;
for (const ValueType& innerVec : vec)
result += toString(innerVec);

return result; // return the concatenated string
}
}

现在您可以调用 toStringstd::vector<std::vector<A>>以及std::vector<A> aObjs , 和 std::vector< /* primitive types */ >也是。

( See Complete Demo Online Live )


Do I just provide at least one specialization of toString for that type? Does the template mechanism sort all this out?

模板特化也是另一种选择。但是,如果您可以访问 C++17,我建议采用上述方式,它将对您在问题中提供的所有类型进行排序。

关于c++ - 如何将各种类型的 vector 转换为 std::string?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63642709/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com