如何在C++中设置两个相似的msg属性,重复代码较少?

How to set two similar msg's attributes with less duplicate codes in C++?

提问人:aliveforu 提问时间:5/30/2023 更新时间:5/30/2023 访问量:55

问:

如何在C++中设置变量属性,使用更少的重复代码?

A.原型

syntax = "proto3";

package Test1;

message A{
    double x = 1;
    double y = 2;
    double z = 3;
    double theta = 4;
    double kappa = 5;
    float s = 6;
    float v = 7;
    float a = 8;
}

B.原型

syntax = "proto3";

package Test2;

message A{
    double x = 1;
    double y = 2;
    double z = 3;
    double theta = 4;
    double kappa = 5;
    float s = 6;
    float v = 7;
    float a = 8;
}

主要

#include <iostream>
#include "A.pb.h"
#include "B.pb.h"

void fun(){
    Test1::A t1;
    Test2::A t2;
    // t1's assignment, no need to care
    t1.set_x(1.0);
    t1.set_y(2.0);
    t1.set_z(3.0);
    t1.set_theta(4.0);
    t1.set_kappa(5.0);
    t1.set_s(6.0);
    t1.set_v(7.0);
    t1.set_a(8.0);

    // t2 = static_cast<Test2::A>(t1); can't cast

    // t2's assignment by t1
    // Is there any other ways set t2 by t1's attribute?
    t2.set_x(t1.x());
    t2.set_y(t1.y());
    t2.set_z(t1.z());
    t2.set_theta(t1.theta());
    t2.set_kappa(t1.kappa());
    t2.set_s(t1.s());
    t2.set_v(t1.v());
    t2.set_a(t1.a());
    
    // something about t2....
    std::cout << t2.z() << std::endl;
}

int main(){
    fun();
}

上面 proto 定义的两个 msg,除了 NAMESPACE 之外,它们的属性几乎相同,由于某些原因,它们的命名空间无法更改。那么有没有其他方法通过 t1 的属性设置 t2?

C++ Protocol-Buffers 复制构造函数

评论

0赞 paddy 5/30/2023
也许你可以使用导入
0赞 Igor Tandetnik 5/30/2023
你可能应该安排一些事情,这样你就不会有两个不同的原型,首先具有相同的内容。

答:

3赞 for_stack 5/30/2023 #1

最好的方法是重新设计你的 protos,并将这些公共属性放入一条消息中,并在两者中引用此消息,并使用 import 引用此消息。Test1::ATest2::A

package util;

message Common {
   // fileds...
}

package Test1;
message A {
  util::Common attr = 1;
}

package Test2;
message A {
  util::Common attr = 1;
}

Test1::A t1;
// set t1.attr.xxx

Test2::A t2;
// copy common attr
*(t2.mutable_attr()) = t1.attr();

由于 和 完全相同,因此还有另一种性能较低的解决方案,并且您不需要更改原型定义:序列化为字符串,并使用序列化字符串进行构造。Test1::ATest2::At1t2

string s;
t1.SerializeToString(&s);
t2.ParseFromString(s);