如果不包含头文件,则无法定义本机运算符的结果,这是不是很麻烦?
根据此页面,size_t在头文件cstddef,cstdio,cstring,ctime和cstdlib中定义.因此,如果这些标题都不包括在内,那么size_t应该是未定义的.但是,以下程序在没有任何警告的情况下编译(使用MSVC 2015RC).
int main()
{
auto d_Size = sizeof( int );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它似乎size_t在本机类型和typedef之间有点混蛋.标准说什么?
标准中哪些函数不允许返回函数?我知道它们在概念上是荒谬的,但在我看来,语法会允许它们.根据这个网页," noptr-declarator [是]任何有效的声明符 ",它将包含一个函数的声明符:
int f()();
Run Code Online (Sandbox Code Playgroud)
关于语法.
在我看来,[dcl.decl]中拼写的语法允许
int f(char)(double)
Run Code Online (Sandbox Code Playgroud)
这可以解释为功能 f ,需要一个 char 并返回相同的签名功能 int g(double).
1 declarator:
2 ptr-declarator
3 noptr-declarator parameters-and-qualifiers trailing-return-type
4 ptr-declarator:
5 noptr-declarator
6 ptr-operator ptr-declarator
7 noptr-declarator:
8 declarator-id attribute-specifier-seq opt
9 noptr-declarator parameters-and-qualifiers
10 noptr-declarator [ constant-expression opt ] attribute-specifier-seq opt
11 ( ptr-declarator )
12 parameters-and-qualifiers:
13 ( parameter-declaration-clause ) cv-qualifier-seqAfter
Run Code Online (Sandbox Code Playgroud)
粗略地说,在1-> 2,2 = 4,4-> 6,4-> 6后你应该有ptr-operator ptr-operator ptr-operator然后,使用4-> 5,5 = 7,7-> 8第一个宣告者; 对第二和第三个声明符使用4-> 5,5 = 7,7-> …
在文件中C:\Program Files (x86)\Windows Kits\8.1\Include\um\OleAuto.h,我发现以下代码,我不知道如何解释:
WINOLEAUTAPI SafeArrayAccessData(_In_ SAFEARRAY * psa,
_Outptr_result_buffer_(_Inexpressible_(psa->cbElements *
product(psa->rgsabound[0..psa->cDims-1]->cElements)))
void HUGEP** ppvData);
Run Code Online (Sandbox Code Playgroud)
请注意方括号内的双倍期.这是C++中的新运算符吗?
这个问题是关于模板和Visual Studio C++ 2013中带有flag/Za的静态积分常量之间的关系.它对boost库有影响.
首先,让我们检查没有模板的代码:
struct easy
{
static const int a = 5;
const int b;
easy( int b_ ) : b( std::max( b_, a ) )
{}
};
const int easy::a;
int main()
{
easy d_Easy( 0 );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
根据编译器选项/ Za的手册页:"在标准(/ Za)下,您必须为数据成员制定一个类外定义".该页面中的示例和上面的代码声明了类中的静态常量,并在那里指定了它的值.在此链接中解释了对类外定义的需求.
现在,让我们看看模板的问题.
template< class T >
struct problem
{
static const int a = 5;
const int b;
problem( int b_ ) : b( std::max( b_, a ) )
{}
}; …Run Code Online (Sandbox Code Playgroud) 就我在标准中看到的而言,以下代码是有效的.它在MSVC1025中编译.
const struct omg;
struct omg volatile;
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
预选赛const和volatile似乎在这些声明漫无目的.他们既不帮助也不伤害编译器和程序员.
该标准似乎并未倾向于消除这些"空洞的模糊".在空声明的情况下,;明确允许.
在预处理之后,还有其他令牌的情况与表达的含义无关吗?
从实用的角度来看,我明白,这两个typedef和test有点"多余"的需要,如果我们希望下面的代码编译被删除:
template< typename type_t >
typedef struct tagTest
{
int a;
} test;
Run Code Online (Sandbox Code Playgroud)
但是,我认为typedef声明集是声明集的子集.他们碰巧有那个特定的decl-specifier.这是我的合理化
typedef struct tagTest
{
int a;
} test;
Run Code Online (Sandbox Code Playgroud)
引入标识符test 并声明结构tagTest.如果该解释是正确的,则标准中的以下段落应该允许template typedef(尽管不具有关键字给出的含义using).
模板声明中的声明应 - (1.1)声明或定义函数,类或变量,或 - (1.2)定义成员函数,成员类,成员枚举或静态数据成员类模板或嵌套在类模板中的类,或 - (1.3)定义类或类模板的成员模板,或 - (1.4)是别名声明.
我在推理中看不出错误,但结论是非法的.
解决上述难题的标准的相关部分是什么?
更新
上述推理的一部分使用typedef struct声明结构的事实.该typedef说明符,据我的理解,意味着声明的任何变量是真正的类型.也就是说,从仅仅变量typedef升级test到等同于声明的类型tagTest.这就是为什么以下代码编译(尽管有警告).
typedef struct tagTest
{
int a;
};
tagTest t;
Run Code Online (Sandbox Code Playgroud)
其中一个答案可以解决多余的问题test.但是,可以在没有声明符的情况下使用typedef,因为 "声明命名的类/结构/联合或命名的枚举时,Init-declarator-list是可选的"
是否可以在不创建临时对象的情况下分配一对成员?
#include <tuple>
using namespace std;
pair< bool, int > foo()
{
return make_pair( false, 3 );
}
int main()
{
int x;
bool y;
auto z = foo();
x = z.second;
y = z.first;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,对象auto z需要在解析之前"保持"该对,但是在实际代码中它的创建可能是昂贵的.
虽然结构的名称在名称空间内的结构集中必须是唯一的,但这样的名称可以与变量和函数"共享".例如,以下代码编译得很好:
// Code 1
struct h{};
int h{ 8 };
Run Code Online (Sandbox Code Playgroud)
同样,没有碰撞:
// Code 2
struct h{};
void h(){}
Run Code Online (Sandbox Code Playgroud)
1)允许该名称共享的原因是什么?
而且,如果我们将模板放入混合中,我们会遇到一些奇怪的情况.代码
// Code 3
template< class H > void h(){}
struct h{};
template< class H > struct j{};
void j(){}
Run Code Online (Sandbox Code Playgroud)
编译; 但以下代码失败:
// Code 4
struct h{};
template< class H > void h(){}
void j(){}
template< class H > struct j{};
Run Code Online (Sandbox Code Playgroud)
2)为什么允许代码2不足以允许代码4的推理?我不是在询问标准中的规则.我在问这些规则背后的原因.
当第一个声明被注释掉时,以下命名空间定义无法编译.如果第一个声明foo是取消注释的,那么它编译就好了.
namespace Y
{
//void foo();
void ::Y::foo(){}
}
Run Code Online (Sandbox Code Playgroud)
标准中的相关部分(§8.31)说:
当declarator-id被限定时,声明应引用先前声明的成员
据我所知,此规则可防止将名称引入其他名称空间.我想知道是否可以放宽该规则以允许引用当前命名空间的qualified-id.
在以下代码中,除了构造函数之外,模板结构BB和CC几乎相同.模板BB使用不执行任何操作的构造函数,而模板CC使用默认构造函数.当我使用Visual Studio 2013更新4编译它时,在声明constInst2但不在声明的行上的行中抛出错误constInst:
错误C4700:未初始化的局部变量'instance2'使用"
我在初始化'instance'时也预料到同样的错误.我误解了这句话吗?
"如果隐式声明的默认构造函数未被删除或无关紧要,则编译器会定义它(即,生成并编译函数体),它与具有空体的用户定义构造函数具有完全相同的效果.空的初始化列表."
struct AA
{
typedef int a;
typedef const int b;
};
template< typename A >
struct BB
{
typename A::a a_A;
typedef typename A::b a_B;
BB()
{};
};
template< typename A >
struct CC
{
typename A::a a_A;
typedef typename A::b a_B;
CC() = default;
};
int main()
{
BB< AA > instance;
BB< AA >::a_B constInst( instance.a_A );
CC< AA > instance2;
CC< AA >::a_B constInst2( instance2.a_A …Run Code Online (Sandbox Code Playgroud) c++ ×9
c++11 ×5
templates ×2
boost ×1
c++14 ×1
constructor ×1
declaration ×1
namespaces ×1
sizeof ×1
standards ×1
windows ×1