从C ++类自动生成属性成员到字符串?

时间:2014-06-05 13:11:20

标签: c++ string

我正在用C ++编程(仍然是初学者),我想知道一个关于自动将类成员生成为字符串的问题,例如:

class Point
{
private:
int x;
int y;

public:
std::list<std::string> getValues();
}

在我看来,我认为我必须编写函数getValues,将int转换为字符串并将字符串放入列表并返回列表,但是我的导师问我是否有办法自动执行此功能,写代码,我不知道如何回答。

因为如果我们添加一个新的成员值(例如:int z),我们将不得不重新编写函数getValues()。显然在Java中有一些方法可以做到这一点,但我想知道是否有类似的方法进入C ++。

祝你好运

4 个答案:

答案 0 :(得分:3)

很难说你的导师真的想要你,但如果我是你的导师,我很乐意你了解Boost.Fusion Adapted Structures及其所依据的技术(特别是打字图)。

Boost.Fusion示例:

#include <boost/fusion/adapted/struct/define_struct.hpp>
#include <boost/fusion/algorithm/iteration/fold.hpp>

#include <boost/lexical_cast.hpp>

#include <iterator>
#include <list>
#include <string>
#include <iostream>

BOOST_FUSION_DEFINE_STRUCT(
    (), Point,
    (int, x)
    (long, y)
    (double, z)
)

template <class Itr> struct collector_t
{
    using result_type = Itr;

    template <class T>
    Itr operator()(Itr itr, T const& val) const { *itr = boost::lexical_cast<std::string>(val); return ++itr; }
};


int main()
{
    Point p {123, 456l, 123.456};

    // create and populate the resulting list using boost.fusion facilities
    std::list<std::string> strings;
    auto sink = std::back_inserter(strings);
    boost::fusion::fold(p, sink, collector_t<decltype(sink)>());

    // dump the resulting list to prove the example
    for (auto s: strings) std::cout << s << '\n';

    return 0;
}

答案 1 :(得分:1)

在C ++中无法自动执行此操作。这需要反思,即代码必须能够推断出一个类的字段。这在C ++中是不可能的。它可以在Java中使用,所以你是对的,可以用Java自动完成。

答案 2 :(得分:1)

以非自动方式:使用访问(编译时)。

class Point {
public:
    //
    // With visitation (names are optional)
    //
    template <typename Visitor>
    void visit(Visitor&& visitor) {
        visitor("x", x);
        visitor("y", y);
    }

    template <typename Visitor>
    void visit(Visitor&& visitor) const {
        visitor("x", x);
        visitor("y", y);
    }

    //
    // With tuples
    //
    auto as_tuple() -> std::tuple<int&, int&> {
        return std::tie(x, y);
    }

    auto as_tuple() const -> std::tuple<int const&, int const&> {
        return std::tie(x, y);
    }

private:
    int x;
    int y;
};

是的,这些解决方案需要更多维护。但是,所有代码都是公开而无需在心理上扩展宏。因此,潜在的编译错误消息往往更清晰,理解也得到了缓解。

维护负担?

  • 您可以自动化(单元测试)两种方法的相关性(确保它们以相同的顺序返回相同数量的成员)
  • 自动检测不完整的方法稍微困难一点,但如果一个成员缺失并经过测试,它也会显示

注意:我个人更喜欢as_tuple版本,它使==<的编写变得如此简单。

注意:可以使用sizeof和ABI规则尝试检测不完整的方法(缺少成员)。

答案 3 :(得分:0)

问题实际上有两个部分:

  1. 查找所有成员和
  2. 将它们转换为字符串。
  3. 在纯C ++中找不到成员,因为它没有任何形式的反射。您可以使用Boost.Fusion之类的标准预处理器来使用特殊声明宏,或者您可以使用自己的预处理器,如OpenC++或使用Clang前端。

    为了转换为字符串,标准方法将是这样的:

    template <typename T>
    std::string to_string(T const &v) {
        std::stringstream s;
        s << v;
        return s.str();
    }
    

    您可以避免输入此内容并使用Boost.Lexical Cast

    请注意,C ++ 11也有std::to_string,但它仅为数字类型定义,因此对此目的不是很有用。