C++ 中的转储工具,如 PHP 中的 var_dump()?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/828989/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dump facility in C++ like var_dump() in PHP?
提问by Duncan Benoit
When I was in college i did some C/C++, but in near future i was working in PHP, and now I wish to put more time in learning C/C++.
我在大学的时候做过一些 C/C++,但在不久的将来我在 PHP 工作,现在我想把更多的时间花在学习 C/C++ 上。
In PHP i was using print_r() or var_dump() in order to display datas from structures or arrays. Do I have such a default functionality in C, in order to see what do i have in a struct or array?
在 PHP 中,我使用 print_r() 或 var_dump() 来显示结构或数组中的数据。我在 C 中有这样的默认功能,以便查看结构或数组中的内容吗?
采纳答案by Duncan Benoit
There is no such functionality in C++. You can of course write your own Dump() functions. The reason such a feature cannot be generally provided is that the C++ compilation process removes the object metadata needed to structure the dump output. You can of course display structure contents in a debugger, where such metadata is maintained in the debug information.
C++ 中没有这样的功能。您当然可以编写自己的 Dump() 函数。通常无法提供此类功能的原因是 C++ 编译过程删除了构建转储输出所需的对象元数据。您当然可以在调试器中显示结构内容,这些元数据保存在调试信息中。
BTW, are you asking about C or C++? The two languages are quite different, both in features and approach, although neither has var_dump() or similar.
BTW,你问的是C还是C++?这两种语言在特性和方法上都非常不同,尽管它们都没有 var_dump() 或类似的。
回答by daminetreg
C++ in itself doesn't provide something like var_dump, but with libraries like Boost.Fusion and the ADAPT_STRUCT and ADAPT_ADT facility it's easily doable.
C++ 本身不提供类似 var_dump 的东西,但使用 Boost.Fusion 和 ADAPT_STRUCT 和 ADAPT_ADT 工具之类的库,它很容易实现。
Indeed as told in the other response, the C++ compiler doesn't generate the metadata needed to generate such an output. However it is possible to generate these metadata and use a bit of template metaprogramming to use them.
事实上,正如其他回复中所说,C++ 编译器不会生成生成此类输出所需的元数据。然而,可以生成这些元数据并使用一些模板元编程来使用它们。
That way I've implemented here an adapted_struct_printer, which can print std::container, any classes or structures, boost::variant and boost::tuple.
这样我在这里实现了一个adapted_struct_printer,它可以打印std::container、任何类或结构、boost::variant 和boost::tuple。
New solution
新解决方案
Now you can easily do the following :
现在您可以轻松地执行以下操作:
#include <iostream>
#include <pre/json/to_json.hpp>
struct customer {
std::string name;
size_t money_spent;
std::vector<std::string> interests;
};
BOOST_FUSION_ADAPT_STRUCT(customer,
name,
money_spent,
interests)
...
customer my_customer{
"Mr. Dupond",
1000,
{"sport articles", "food", "tools"}
};
std::cout << pre::json::to_json(my_customer) << std::endl;
You can inversely with this library also do from_json to populate structures from json.
您也可以使用此库逆向执行 from_json 以从 json 填充结构。
A documentation is available here : http://daminetreg.github.io/lib-cpp-pre/html/namespacepre_1_1json.html#a4325d2cdd64a7e321303fd4428f298b9
此处提供文档:http: //daminetreg.github.io/lib-cpp-pre/html/namespacepre_1_1json.html#a4325d2cdd64a7e321303fd4428f298b9
OLD Response
旧响应
The only requirement is that you call BOOST_FUSION_ADAPT_STRUCT/BOOST_FUSION_ADAPT_ADT on your classes (See http://www.boost.org/doc/libs/1_57_0/libs/fusion/doc/html/fusion/adapted.html)
唯一的要求是您在您的课程上调用 BOOST_FUSION_ADAPT_STRUCT/BOOST_FUSION_ADAPT_ADT(参见http://www.boost.org/doc/libs/1_57_0/libs/fusion/doc/html/fusion/adapted.html)
So that this example :
所以这个例子:
#include <iostream>
#include <swissarmyknife/boost/fusion/adapted_struct_printer.hpp>
#include <boost/fusion/include/define_struct.hpp>
#include <boost/variant.hpp>
#include <boost/tuple/tuple.hpp>
namespace bla {
struct someclass {
int i = 12;
int j = 15;
};
using boost::fusion::detail::operator <<;
}
BOOST_FUSION_ADAPT_STRUCT(bla::someclass,
(int, i)
(int, j)
)
BOOST_FUSION_DEFINE_STRUCT((bla), innerbim,
(std::string, mystring)
)
BOOST_FUSION_DEFINE_STRUCT((bla), bimbim,
(int, boom)
(int, bam)
(bla::innerbim, my_inner_bim)
)
typedef boost::variant<int, double, bla::innerbim> myvariant_t;
typedef boost::tuple<std::string, int, bla::innerbim, myvariant_t> my_tuple_t;
BOOST_FUSION_DEFINE_STRUCT((bla), blabla,
(bla::bimbim, bim)
(int, i)
(int, j)
(std::vector<double>, list)
(std::list<bla::bimbim>, list_of_bimbim)
(my_tuple_t, mytuple)
(myvariant_t, myvariant)
)
int main(int argc, char** argv) {
using namespace swak;
bla::blabla instance{
{22, 12, bla::innerbim{"COOL"} },
23,
43,
{2.00, 39.07, 24.05},
{
{24, 9, bla::innerbim{"FEEL GOOD"} },
{26, 14, bla::innerbim{"SO BAD"} },
},
{"Hey that's not an int", 1, bla::innerbim{"hello"}, 12},
bla::innerbim("I'm in the variant")
};
std::cout << instance << std::endl;
bla::someclass otherinstance{};
std::cout << "Other instance : " << otherinstance << std::endl;
return 0;
}
Prints out the following :
打印出以下内容:
{
bim :
{
boom : 22,
bam : 12,
my_inner_bim :
{
mystring : COOL,
}
}
i : 23,
j : 43,
list : [2, 39.07, 24.05],
list_of_bimbim : [
{
boom : 24,
bam : 9,
my_inner_bim :
{
mystring : FEEL GOOD,
}
}
,
{
boom : 26,
bam : 14,
my_inner_bim :
{
mystring : SO BAD,
}
}
],
mytuple :
{
0 (Ss) : Hey that's not an int,
1 (i) : 1,
2 (N3bla8innerbimE) :
{
mystring : hello,
}
3 (N5boost7variantIidN3bla8innerbimENS_6detail7variant5void_ES5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_S5_EE) :
{
12}
}
myvariant :
{
{
mystring : I'm in the variant,
}
}
}
Other instance :
{
i : 12,
j : 15,
}
I'm improving the implementation to get it at some point as a possible new feature in boost fusion, but it's already usable as shown there :
我正在改进实现,以便在某个时候将其作为 boost fusion 中的一个可能的新功能,但它已经可以使用了,如下所示:
回答by robocat
It is possible but it would take a lot of work if debug symbols were enabled and all optimisations were disabled. Also it would be slow and perhaps not very reliable[*1].
这是可能的,但如果启用调试符号并禁用所有优化,则需要大量工作。而且它会很慢,而且可能不太可靠[*1]。
Anything that a debugger can do could be replicated by a dump() function that causes a breakpoint, and logged out information.
调试器可以做的任何事情都可以通过 dump() 函数复制,该函数会导致断点并注销信息。
Some debuggers can be automated, so perhaps the dump function itself would be written in the debugger.
一些调试器可以自动化,因此转储函数本身可能会写在调试器中。
*1 e.g. debuggers sometimes crash when dealing with some breakpoints. e.g. the program would need to have a breakpoint and halt all threads before trying to dump data. e.g. programs that need to deal with realtime interrupts probably wouldn't work. e.g. the debugger needs to be reliable enough to deal with many many breakpoints and not introduce other issues.
*1 例如,在处理某些断点时,调试器有时会崩溃。例如,在尝试转储数据之前,程序需要有一个断点并停止所有线程。例如,需要处理实时中断的程序可能无法工作。例如,调试器需要足够可靠以处理许多断点并且不引入其他问题。
回答by MadsonJr
In microsoft article have some solution:
在微软文章中有一些解决方案:
vector::push_back
矢量::push_back
https://msdn.microsoft.com/pt-br/library/7fthz5xd.aspx
https://msdn.microsoft.com/pt-br/library/7fthz5xd.aspx
template <typename T> void print_elem(const T& t) {
cout << "(" << t << ") ";
}
template <typename T> void print_collection(const T& t) {
cout << " " << t.size() << " elements: ";
for (const auto& p : t) {
print_elem(p);
}
cout << endl;
}
and the call for this:
并呼吁:
cout << "vector data: " << endl;
print_collection(v);
回答by dirkgently
No, you have to roll your own using one from the coutor C style printffamily of output functions for user defined data structures. Similarly, for arrays, (except C-style strings) you will have to loop over all the elements and print each one.
不,您必须使用用户定义的数据结构的cout或 C 风格printf的输出函数系列中的一个来推出自己的。类似地,对于数组(C 样式字符串除外),您必须遍历所有元素并打印每个元素。

