c++ 打包结构成员的模板赋值函数

kb5ga3dv  于 2023-05-20  发布在  其他
关注(0)|答案(1)|浏览(118)

如何编写模板函数来实现这种打包结构成员的模板赋值
在我的项目中,使用了一个模板赋值函数来避免各种隐式转换问题。代码如下

template<typename LHS, typename RHS> inline LHS &assign(LHS &lhs, RHS rhs) {
    return lhs = static_cast<LHS>(rhs);
}

int main() {
    int a = 3;
    long b = 0;
    a = b;  // warning if -Wconversion enabled
    assign(a, b); // no warning 
}

这个很好用。但最近,我需要在代码中添加packed struct并为memeber赋值。模板赋值函数不再工作。

struct __attribute__((packed)) Data
{
    int m;
    int n;
};

template<typename LHS, typename RHS> inline LHS &assign(LHS &lhs, RHS rhs) {
    return lhs = static_cast<LHS>(rhs);
}

int main() {
    int a = 3;
    long b = 0;
    Data d;
    assign(a, b);  // works fine 
    assign(d.m, a);  // error: cannot bind packed field ‘d.Data::m’ to ‘int&’
}
iibxawm4

iibxawm41#

你不能将一个非常量引用绑定到一个位域(__attribute__((packed))本质上是从int m成员变量中创建一个位域)。
但是,您可以将对象作为一个整体传递,并在此赋值操作中赋值位域:

struct __attribute__((packed)) Data
{
    int m;
    
    Data(int value): m{ value } {}
};

template<typename LHS, typename RHS> inline LHS &assign(LHS &lhs, const RHS& rhs) {
    return lhs = static_cast<LHS>(rhs);
}

int main() {
    Data d{ 2 };
    long b = 0;
    // static_cast<Data>(b) actually creates a temporary and assigns it to the Data object
    assign(d, b);
    return d.m;
}

相关问题