从C+;自动将属性成员生成字符串+;上课? 我在C++中编程(还是初学者),我想知道一个关于自动生成类的值成员到字符串的问题:例如: class Point { private: int x; int y; public: std::list<std::string> getValues(); } 类点 { 私人: int x; int-y; 公众: std::list getValues(); }

从C+;自动将属性成员生成字符串+;上课? 我在C++中编程(还是初学者),我想知道一个关于自动生成类的值成员到字符串的问题:例如: class Point { private: int x; int y; public: std::list<std::string> getValues(); } 类点 { 私人: int x; int-y; 公众: std::list getValues(); },c++,string,C++,String,在我看来,我认为我必须编写函数getValues,将int转换成字符串,将字符串放入列表并返回列表,但我的导师问我是否有办法自动完成此函数,而不必编写代码,我不知道如何回答 因为如果我们添加了一个新的成员值(EX:INTZ),我们将不得不重新定义函数GETValueSUSER()。显然,在java中有一些方法可以做到这一点,但是我想知道C++中是否有类似的方式。 诚挚的问候,< p>在C++中没有办法自动完成。这需要反射,也就是说,代码必须能够对类所具有的字段进行推理。这在C++中是不可能的。在

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

因为如果我们添加了一个新的成员值(EX:INTZ),我们将不得不重新定义函数GETValueSUSER()。显然,在java中有一些方法可以做到这一点,但是我想知道C++中是否有类似的方式。


诚挚的问候,

< p>在C++中没有办法自动完成。这需要反射,也就是说,代码必须能够对类所具有的字段进行推理。这在C++中是不可能的。在java中是可能的,所以你是对的,可以在java中自动完成。

C++中没有办法自动完成。这需要反射,也就是说,代码必须能够对类所具有的字段进行推理。这在C++中是不可能的。这在Java中是可能的,所以你是对的,你可以用Java自动做到这一点。

很难说你的导师真正想从你那里得到什么,但如果我是你的导师,我希望你了解它所基于的技术(特别是类型映射)

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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
BOOST\u FUSION\u DEFINE\u STRUCT(
()点,
(int,x)
(长,y)
(双倍,z)
)
模板结构收集器\u t
{
使用结果_type=Itr;
模板
Itr操作符()(Itr-Itr,T const&val)const{*Itr=boost::lexical_cast(val);return++Itr;}
};
int main()
{
点p{123,456l,123.456};
//使用boost.fusion工具创建并填充结果列表
std::列表字符串;
自动接收器=标准::背面插入器(字符串);
boost::fusion::fold(p,sink,collector_t());
//转储结果列表以验证示例

对于(auto s:strings)std::cout来说,很难说你的导师真正想要你做什么,但如果我是你的导师,我希望你了解它的原理和技术(尤其是类型图)

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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
BOOST\u FUSION\u DEFINE\u STRUCT(
()点,
(int,x)
(长,y)
(双倍,z)
)
模板结构收集器\u t
{
使用结果_type=Itr;
模板
Itr操作符()(Itr-Itr,T const&val)const{*Itr=boost::lexical_cast(val);return++Itr;}
};
int main()
{
点p{123,456l,123.456};
//使用boost.fusion工具创建并填充结果列表
std::列表字符串;
自动接收器=标准::背面插入器(字符串);
boost::fusion::fold(p,sink,collector_t());
//转储结果列表以验证示例

对于(auto s:strings)std::cout问题实际上有两部分:

  • 查找所有成员和
  • 将它们转换为字符串
  • 在纯C++中发现成员是不可能的,因为它没有任何形式的反射。你可以使用标准的预处理器,比如DO,或者使用你自己的预处理器,或者使用CLAN前端。 对于转换为字符串,标准方法如下:

    template <typename T>
    std::string to_string(T const &v) {
        std::stringstream s;
        s << v;
        return s.str();
    }
    
    模板
    标准::字符串到_字符串(T常量和v){
    std::strings;
    
    这个问题实际上有两个部分:

  • 查找所有成员和
  • 将它们转换为字符串
  • 在纯C++中发现成员是不可能的,因为它没有任何形式的反射。你可以使用标准的预处理器,比如DO,或者使用你自己的预处理器,或者使用CLAN前端。 对于转换为字符串,标准方法如下:

    template <typename T>
    std::string to_string(T const &v) {
        std::stringstream s;
        s << v;
        return s.str();
    }
    
    模板
    标准::字符串到_字符串(T常量和v){
    std::strings;
    
    以非自动化的方式:使用访问(编译时)

    类点{
    公众:
    //
    //带探视(姓名可选)
    //
    模板
    无效访问(访客和访客){
    访客(“x”,x);
    访客(“y”,y);
    }
    模板
    无效访问(访客和访客)常量{
    访客(“x”,x);
    访客(“y”,y);
    }
    //
    //带元组
    //
    自动作为tuple()->std::tuple{
    返回标准::连接(x,y);
    }
    自动作为tuple()常量->标准::tuple{
    返回标准::连接(x,y);
    }
    私人:
    int x;
    int-y;
    };
    
    是的,这些解决方案需要更多的维护。但是,所有代码都是公开的,不需要在心里扩展宏。因此,潜在的编译错误消息往往更清晰,理解也更容易

    至于维修负担呢

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

    注意:我个人更喜欢
    作为tuple
    版本,它可以以非自动方式编写
    =
    :使用访问(编译时)

    类点{
    公众:
    //
    //带探视(姓名可选)
    //
    模板
    无效访问(访客和访客){
    访客(“x”,x);
    访客(“y”,y);
    }
    模板
    无效访问(访客和访客)常量{
    访客(“x”,x);
    访客(“y”,y);
    }
    //
    //带元组
    //
    自动作为tuple()->std::tuple{
    返回标准::连接(x,y);
    }
    自动作为tuple()常量->标准::tuple{
    返回标准: