我需要语法帮助,如下所示访问结构中的联合。编译器抱怨我需要在下面命名“innerStruct”定义,而不是使用匿名内部结构。有人可以解释规则,以及如何初始化构造函数字段并命名为bit字段元素。我有一个 live coliru demo 来显示代码。
不幸的是,该代码无法编译,因为它指示以下错误:
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In constructor 'Foo::Foo(uint8_t, uint8_t)':
main.cpp:38:11: error: class 'Foo' does not have any field named 'asUint8'
, asUint8(aBitFields)
^
main.cpp: In function 'std::ostream& operator<<(std::ostream&, const Foo&)':
main.cpp:54:83: error: 'const struct Foo' has no member named 'innerStruct'
<< "], mA[0x" << std::setw(2) << std::setfill('0') << std::hex << rhs.innerStruct.mA
^
main.cpp:55:83: error: 'const struct Foo' has no member named 'innerStruct'
<< "], mB[0x" << std::setw(2) << std::setfill('0') << std::hex << rhs.innerStruct.mB
^
main.cpp:56:83: error: 'const struct Foo' has no member named 'innerStruct'
<< "], mC[0x" << std::setw(2) << std::setfill('0') << std::hex << rhs.innerStruct.mC
^
main.cpp:57:83: error: 'const struct Foo' has no member named 'innerStruct'
<< "], mD[0x" << std::setw(2) << std::setfill('0') << std::hex << rhs.innerStruct.mD
^
struct Foo {
// fields
uint8_t mType;
union innerUnion_t {
struct innerStruct_t {
uint8_t mA : 2;
uint8_t mB : 1;
uint8_t mC : 2;
uint8_t mD : 3;
} innerStruct;
uint8_t asUint8;
} innerUnion;
// constructor
explicit Foo() = default;
// constructor
explicit Foo(
const uint8_t aType,
const uint8_t aBitFields)
: mType(aType)
, asUint8(aBitFields)
{}
/**
* Stream insert operator<p>
*
* @param os [in,out] output stream
* @param rhs [in] Foo to send to the output
* stream.
*
* @return a reference to the updated stream
*/
friend std::ostream& operator<<(
std::ostream& os, const Foo& rhs) {
os << "Foo"
<< ": type[0x" << std::setw(2) << std::setfill('0') << std::hex << rhs.mType
<< "], mA[0x" << std::setw(2) << std::setfill('0') << std::hex << rhs.innerStruct.mA
<< "], mB[0x" << std::setw(2) << std::setfill('0') << std::hex << rhs.innerStruct.mB
<< "], mC[0x" << std::setw(2) << std::setfill('0') << std::hex << rhs.innerStruct.mC
<< "], mD[0x" << std::setw(2) << std::setfill('0') << std::hex << rhs.innerStruct.mD
<< "]";
return os;
}
};
编辑
注意:在对结构定义稍作更改的建议答案之后,我还有一个其他问题,关于初始化或引用位字段mA-> mD的语法是什么,我在构造函数中尝试使用以下语法,但它也不编译。我试图命名innerUnion并将其命名的嵌套结构明确称为 innerUnion.innerStruct.mA(1)-请参见 second live demo
它给出以下错误:
main.cpp: In constructor 'Foo::Foo(uint8_t, uint8_t)':
main.cpp:39:21: error: expected '(' before '.' token
, innerUnion.innerStruct.mA(1)
^
main.cpp:39:21: error: expected '{' before '.' token
最佳答案
您只需要在代码中删除一些单词即可:
#include <memory>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
template<typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec)
{
for (auto& el : vec)
{
os << el << ' ';
}
return os;
}
struct Foo {
// fields
uint8_t mType;
union {
struct {
uint8_t mA : 2;
uint8_t mB : 1;
uint8_t mC : 2;
uint8_t mD : 3;
} innerStruct;
uint8_t asUint8;
};
// constructor
explicit Foo() = default;
// constructor
explicit Foo(
const uint8_t aType,
const uint8_t aBitFields)
: mType(aType)
, asUint8(aBitFields)
{}
/**
* Stream insert operator<p>
*
* @param os [in,out] output stream
* @param rhs [in] Foo to send to the output
* stream.
*
* @return a reference to the updated stream
*/
friend std::ostream& operator<<(
std::ostream& os, const Foo& rhs) {
os << "Foo"
<< ": type[0x" << std::setw(2) << std::setfill('0') << std::hex << rhs.mType
<< "], mA[0x" << std::setw(2) << std::setfill('0') << std::hex << rhs.innerStruct.mA
<< "], mB[0x" << std::setw(2) << std::setfill('0') << std::hex << rhs.innerStruct.mB
<< "], mC[0x" << std::setw(2) << std::setfill('0') << std::hex << rhs.innerStruct.mC
<< "], mD[0x" << std::setw(2) << std::setfill('0') << std::hex << rhs.innerStruct.mD
<< "]";
return os;
}
};
int main()
{
std::vector<std::string> words = {
"Hello", "from", "GCC", __VERSION__, "!"
};
std::cout << words << std::endl;
auto pFoo = std::make_unique<Foo>();
std::cout << *pFoo << std::endl;
}
关于c++ - 如何将匿名C++ union 与匿名结构一起使用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34984321/