C++等效于 C 指定的初始值设定项是什么?
What is the C++ equivalent to C's designated initializers?
你可以用C声明一个结构,如下所示:
typedef struct MyStruct {
const char *name;
int (*func1)(void);
int (*func2)(void);
int (*func3)(void);
} MyStruct;
int test_func2(void) {
return 0;
}
MyStruct test_struct = {
.name = "buffer",
.func2 = test_func2,
};
这对于仅定义特定成员非常方便,所有其他成员都设置为 0/NULL。
编辑:特别是,这允许不知道MyStruct如何定义的细节,因此它可以在内部更改,添加新成员等,而无需使用此类型破坏代码。
但是,这不会使用 C++ 编译器进行编译,从而出现错误:
test.c:23: error: expected primary-expression before ‘.’ token
test.c:24: error: expected primary-expression before ‘.’ token
是否有等效的C++宣言实现相同的目标?
谢谢。
编辑:@chris我可以告诉你不明白:)很明显,大多数其他人都在评论我应该使用什么语法,应该如何定义结构等。完全没有抓住重点。这不是关于定义结构的正确方法,这个代码段只是为了提供一个上下文。
至于代码等效性,在代码中的某个地方说你做到了:
MyStruct blah = { NULL, NULL, func2 };
现在 MyStruct 将其定义更改为:
typedef struct MyStruct {
const char *name;
int (*func4)(void);
int (*func1)(void);
int (*func2)(void);
int (*func3)(void);
} MyStruct;
您的代码仍然可以很好地编译,但引入了严重的回归:您现在将初始化 func1 成员,而不是像以前那样设置 func2...
问题是关于是否有C++指定的初始值设定项等效:没有。 问题已关闭。
不,C++不支持 C99 指定的初始值设定项。 如果要按名称设置单个成员,则需要通过分配来完成,例如
MyStruct test_struct = MyStruct();
test_struct.name = "buffer";
test_struct.func1 = test_func1;
正如K-ballo所说, 代码相当于:
MyStruct test_struct = {
"buffer",
test_func1
};
但是由于您使用的是C++,因此应考虑编写和使用MyStruct的构造函数:
struct MyStruct {
const char *name;
int (*func1)(void);
int (*func2)(void);
int (*func3)(void);
MyStruct(const char *n,
int (*f1)(void) = NULL,
int (*f2)(void) = NULL,
int (*f3)(void) = NULL) : name(n), func1(f1), func2(f2), func3(f3) {}
};
请注意,在C++中,您不需要将其键入 MyStruct,即使没有 typedef,您也可以使用 MyStruct(不带结构关键字)。
你可以只使用 lambda(从 C++11 开始)。这将允许您保持声明不变,同时轻松初始化结构的全局/常量实例:
struct Test
{
int x;
float y;
};
const Test test=[]{ Test t{}; t.x=5, t.y=3.3465; return t; }();
#include <iostream>
int main()
{
std::cout << "test.x: " << test.x << ", test.y: " << test.y << "n";
}
您甚至可以将其包装到宏中,尽管在下面的表单中,它只允许固定数量的初始值设定项:
// Macro to simplify it a bit
#define DECL_AND_INIT(Type,object,INIT1,INIT2)
Type object=[]{ Type o{}; o.INIT1; o.INIT2; return o; }()
// Example usage
const DECL_AND_INIT(Test,test1,x=-7,y=-9.325e31);
请注意,您仍然必须像 lambda 中的 Test t{};
一样使用值初始化 — 否则,如果您初始化并非所有成员(例如,由于添加了新成员),您最终将复制导致 UB 的未初始化变量。
此功能等价性将是具有空体的struct
的构造函数:
#ifdef __cplusplus
MyStruct::MyStruct(char* N, int (*F)(void)) :
name(N),
func1(0),
func2(0),
func3(F) {
// empty
}
#endif
(模化一些语法错误,我的C++有点生疏。
这在功能上是等效的,因为它允许您构造全局对象,即使它们具有const
限定字段,并且任何现代编译器都应该在编译时使用静态链接初始化对象。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- C++避免重复声明的语法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- C++中名称篡改的目的是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 是什么阻止DOMTimerCoordinator::NextID进入无休止的循环
- 派生类销毁的最佳实践是什么
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 通过JNI传递数据数组的最快方法是什么
- "using namespace std;"在C++的作用是什么?
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 文件系统:复制功能的速度秘诀是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 是什么原因导致它无法编译?它是声明签名还是在函数本身的实现中
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么