我想要一种尽可能自动地将对象序列化和反序列化为JSON的方法.
序列化:
对我来说,理想的方法是,如果我在实例中调用JSONSerialize(),它将返回一个带有JSON对象的字符串,该对象具有该对象的所有公共属性"name_of_property": "value"
.对于那些作为原语的值,它很简单,对于它应该尝试在每个JSONSerialize()或ToString()上调用的对象来递归序列化所有公共属性.对于集合,它也应该正常运行(只需矢量/数组就可以了).
反序列化:只需创建给定对象的实例(让我们说一只狗)并调用JSONDeserialize(json_string)
,这应该填充所有公共属性,在属性不是基元或需要的集合的情况下创建所需的对象.
一个例子应该像这样运行:
Dog *d1 = new Dog();
d1->name = "myDog";
string serialized = d1->JSONSerialize();
Dog *d2 = new Dog();
d2->JSONDeserialize(serialized);
std::cout << d2->name; // This will print "myDog"
Run Code Online (Sandbox Code Playgroud)
或者像那样:
Dog *d1 = new Dog();
d1->name = "myDog";
string serialized = JSONSerializer.Serialize(d1);
Dog *d2 = JSONSerializer.Deserialize(serialized, Dog);
std::cout << d2->name; // This will print "myDog"
Run Code Online (Sandbox Code Playgroud)
我该如何轻松地将其拉下来?
在用户GMan使用此答案时,我制作了以下代码段(使用Visual C++ 9编译):
class Class {
public:
operator void() {}
};
Class object;
static_cast<void>( object );
(void)object;
object.operator void();
Run Code Online (Sandbox Code Playgroud)
在使用调试器踩到后,我发现转换为void
不调用Class::operator void()
,只有第三个invokation(显式调用运算符)实际上调用了运算符,两个转换只是什么都不做.
为什么operator void
不使用强制语法调用?
使用逗号分隔的参数包的最简单方法是什么std::ostream
?
例:
template<typename... Args>
void doPrint(std::ostream& out, Args... args){
out << args...; // WRONG! What to write here?
}
// Usage:
int main(){
doPrint(std::cout,34,"bla",15); // Should print: 34,bla,15
}
Run Code Online (Sandbox Code Playgroud)
注意:可以假设<<
操作员的相应过载可用于所有类型的参数包.
复合文字是C99结构.即使我可以用C++做到这一点:
#include <iostream>
using namespace std;
int main() {
for (auto i : (float[2]) {2.7, 3.1}) cout << i << endl;
}
Run Code Online (Sandbox Code Playgroud)
似乎MSVC支持它作为扩展.然而,我可以得到所有编译器,编译上面提到的代码.
这是C++ 14中的一个功能吗?是否有一个不同的标准术语(在我看来,只是创建一个临时使用支撑初始化)?
旁注:"复合文字"(或者我应该称之为的任何内容)是包扩展上下文(仅提及功能)
我有以下课程:
template<typename... Tkeys>
class C
{
public:
std::tuple<std::unordered_map<Tkeys, int>... > maps;
// Not real function:
void foo(Tkeys... keys) {
maps[keys] = 1;
}
};
Run Code Online (Sandbox Code Playgroud)
我将如何实现foo
这样它分配给每个std::map
在maps
得到与它匹配的钥匙叫什么名字?
例如,如果我有
C<int, int, float, std::string> c;
Run Code Online (Sandbox Code Playgroud)
我打来电话
c.foo(1, 2, 3.3, "qwerty")
Run Code Online (Sandbox Code Playgroud)
那c.maps
应该相当于
m1 = std::map<int, int>()
m1[1] = 1;
m2 = std::map<int, int>()
m2[2] = 1;
m3 = std::map<float, int>()
m3[3.3] = 1;
m4 = std::map<std::string, int>()
m4["qwerty"] = 1;
c.maps = std::make_tuple(m1, m2, m3, m4);
Run Code Online (Sandbox Code Playgroud) 在C++参考中,我发现了有关C++中允许的属性语法的信息,它是:
[[attribute-list]]
[[ using attribute-namespace : attribute-list ]]
Run Code Online (Sandbox Code Playgroud)
"其中attribute-list是一个逗号分隔的零个或多个属性的序列(可能以省略号结尾...表示包扩展)"
我试过用它,但我发现之间没有区别:
[[deprecated]] void f()
{
}
Run Code Online (Sandbox Code Playgroud)
和
[[deprecated...]] void f()
{
}
Run Code Online (Sandbox Code Playgroud)
在这两种情况下输出都是相同的.
我偶然发现了看起来像这样的旧代码:
void dothing(bool testBool,
const std::string& testString1,
const std::string& file,
int line,
const std::string& defaultString = "")
{
// do something...
}
void dothings(bool testBool,
const std::string& testString1,
const std::string& testString2,
const std::string& file,
int line,
const std::string& defaultString = "")
{
dothing(testBool, testString1, file, line, defaultString);
dothing(testBool, testString2, file, line, defaultString);
}
void dothings(bool testBool,
const std::string& testString1,
const std::string& testString2,
const std::string& testString3,
const std::string& file,
int line,
const std::string& defaultString = "")
{
dothings(testBool, testString1, testString2, file, …
Run Code Online (Sandbox Code Playgroud) 假设我们有类:
class A
{
public:
static void m() {}
}
class B
{
public:
static void m() {}
}
template<typename... T>
class C
{
public:
void c()
{
T::m(); // Call somehow m() of A and B, if T is a parameter pack of A and B
}
}
Run Code Online (Sandbox Code Playgroud)
我如何扩展参数包并为每种类型调用静态方法?
在下面的小程序中,我展示了我目前用于提取类的模板参数并通过递归辅助函数迭代它的解决方案.
我想知道是否有更简洁的方法来做,正如我在下面的评论中的伪代码中解释的那样.
template <int...Is> struct Pack {};
template <int I> struct B
{
static void foo() { std::cout << I << "\n"; }
};
// recursive helper function, also used to extract the parameter pack arguments
template <int I, int...Is>
void foo_helper( Pack<I, Is...>&& )
{
B<I>::foo();
foo_helper( Pack<Is...>{} );
}
// terminate recursion
void foo_helper( Pack<>&& ) {}
struct A
{
typedef Pack<1,3,5> ints;
static void foo()
{
// this is what I do
foo_helper(ints{});
// this is what …
Run Code Online (Sandbox Code Playgroud) 我有一个模板化的类MyClass
,我想为各种参数运行它,以便测量一些值.我知道编译之前的确切参数因此我认为必须有一种方法来实现目标.
我的代码到目前为止:
template <int T>
class MyClass { /*...*/ };
constexpr int PARAMS[] = {1,2,3 /*, ...*/};
for (constexpr auto& t: PARAMS) {
MyClass<t> myClass;
// ... do sth
}
Run Code Online (Sandbox Code Playgroud)
但是编译器(gcc v4.9.2,C++ 11)不接受这一点.我也试过使用const
而不是constexpr
哪个也不行.
有可能是这样的吗?我真的根本不想使用宏.