MSDN 认为匿名结构在C++中是非标准的:
Microsoft C扩展允许您在另一个结构中声明结构变量而不为其指定名称.这些嵌套结构称为匿名结构.C++不允许匿名结构.
您可以访问匿名结构的成员,就好像它们是包含结构中的成员一样.
我被告知这个功能不一定只是创建一个未命名的结构,但我不能看到标准措辞的区别.
C++ 11说:
[C++11: 9/1]:[..]一个类说明符,其类头省略了class-head-name,定义了一个未命名的类.
并为缺少名称的类型定义提供完整的语法结构.
C++ 03缺少这种明确的措辞,但同样表明identifier类型定义中的类型是可选的,并在9.4.2/5和中引用了"未命名的类" 3.5/4.
有没有办法在未命名的类中声明构造函数或析构函数?考虑以下
void f()
{
struct {
// some implementation
} inst1, inst2;
// f implementation - usage of instances
}
Run Code Online (Sandbox Code Playgroud)
后续问题:实例是基于任何基于堆栈的对象构造(和销毁)的.叫什么?它是由编译器自动分配的错位名称吗?
在c ++ 11中传递lambda非常简单:
func( []( int arg ) {
// code
} ) ;
Run Code Online (Sandbox Code Playgroud)
但我想知道,将lambda传递给像这样的函数的成本是多少?如果func将lambda传递给其他函数怎么办?
void func( function< void (int arg) > f ) {
doSomethingElse( f ) ;
}
Run Code Online (Sandbox Code Playgroud)
lambda的传递是否昂贵?由于可以为function对象分配0,
function< void (int arg) > f = 0 ; // 0 means "not init"
Run Code Online (Sandbox Code Playgroud)
它让我认为函数对象就像指针一样.但是,如果不使用new,则意味着它们可能类似于值类型struct或类,它们默认为堆栈分配和成员方式副本.
当你按"值"传递一个函数对象时,C++ 11"代码体"和捕获的变量组是如何传递的?是否有很多代码体的多余副本?我是否必须标记function传递的每个对象,const&以便不进行复制:
void func( const function< void (int arg) >& f ) {
}
Run Code Online (Sandbox Code Playgroud)
或者以某种方式使函数对象以不同于常规C++结构的方式传递?
您将如何在标准C++ 11/14中执行此操作?因为如果我没有弄错的话,这不是带有匿名结构的标准兼容代码.
我希望以与此相同的方式访问成员.
template <typename some_type>
struct vec
{
union {
struct { some_type x, y, z; };
struct { some_type r, g, b; };
some_type elements[3];
};
};
Run Code Online (Sandbox Code Playgroud) 以下代码合法吗?:
struct
{
int x;
};
Run Code Online (Sandbox Code Playgroud)
此代码仅定义了一个未命名的结构。我既不打算创建这种类型的对象,也不需要以其他任何方式使用此结构。它只是作为某些复杂的宏扩展的副作用而出现在源代码中。
虽然没有用,但我认为没有问题。只是可以编译然后完全优化的另一段代码。
但是,在现实世界中,结果与我的预期有很大不同:
GCC 8.3报告错误:
错误:抽象声明符“ <未命名结构>”用作声明
Clang 8.0.0也报告了一个错误:
错误:匿名结构和类必须是类成员
警告:声明未声明任何内容[-Wmissing-declarations]
只有MSVC 2017认为此类来源没有问题。
所以,问题是:谁是对的?标准中是否有明确禁止此类声明的相关引用?
编辑:
该项目使用C ++ 11。但是对于C ++ 98,C ++ 11和C ++ 17,错误消息是相同的。
我们来考虑这个示例代码:
struct sso
{
union {
struct {
char* ptr;
char size_r[8];
} large_str;
char short_str[16];
};
const char* get_tag_ptr() const {
return short_str+15;
}
};
Run Code Online (Sandbox Code Playgroud)
在[basic.expr]中指定只要结果指向数组的另一个元素(或超过对象的末尾或最后一个元素),就允许指针运算.尽管如此,如果数组是联合的非活动成员,则在本节中未指定会发生什么.我相信这不是问题short_str+15,永远不是UB.这样对吗?
以下问题清楚地表明了我的意图
struct vec2
{
union
{
struct { float x, y; };
struct { float r, g; };
struct { float s, t; };
};
vec2() {}
vec2(float a, float b) : x(a), y(b) {}
};
struct vec3
{
union
{
struct { float x, y, z; };
struct { float r, g, b; };
struct { float s, t, p; };
// Here is the problem with g++.
struct { vec2 xy; float z; };
struct { float x; vec2 …Run Code Online (Sandbox Code Playgroud) 我想保留任何其他检查-Wpedantic,但会丢失有关未命名结构的警告error: ISO C++ prohibits anonymous structs [-Wpedantic].
我希望能够做到以下几点:
union
{
struct
{
float x, y, z, w;
};
struct
{
float r, g, b, a;
};
float v[4];
};
Run Code Online (Sandbox Code Playgroud)
我正在使用C++ 11并使用-std=c++11标志进行编译.我已经读过C11支持这个功能,但我还没有看到它在C++ 11中得到支持.
我曾经提到过-fms-extensions:
我尝试了旗帜,它似乎没有任何效果(无论在-fms-extensions和之间排序的排列-Wpedantic).
感谢我的评论,我发现了以下内容:
我仍然想知道是否有一种方法可以启用此gcc扩展(我知道所有编译器都有)将禁用该警告.或者是-Wpedantic全有还是全无?
我想知道是否有人知道是否有可能以某种方式在联盟中使用继承.
在下面的示例中,TestFailsunion将不包含struct中的a变量Base,同时TestWorks确实有效.
struct Base { int a; };
union TestFails
{
struct : public Base {};
int b;
};
union TestWorks
{
struct { int a; };
int b;
};
int main()
{
TestWorks works;
works.a = 0;
TestFails fails;
fails.a = 0;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
您可以在此处测试代码:http://ideone.com/dUzpOR
我想创建一个联合,其中最大的成员是32位整数.这将主要写入.然后有四个8位变量,可能是char类型,每个变量都会引用32位整数类型的不同部分:
union {
int32 myint;
char char1 [7:0];
char char2 [15:8];
char char3 [23:16];
char char4 [31:24];
}
Run Code Online (Sandbox Code Playgroud)
但我不知道如何在C++中这样做.
c++ ×10
c++11 ×5
unions ×3
class ×1
constructor ×1
declaration ×1
destructor ×1
g++ ×1
gcc ×1
glsl ×1
inheritance ×1
lambda ×1
mingw ×1
std-function ×1
struct ×1