小编Hec*_*tor的帖子

隐式构造函数与"空"构造函数

在以下代码中,除了构造函数之外,模板结构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++ constructor

5
推荐指数
1
解决办法
167
查看次数

C++中的多个声明

在[basic.scope.declarative] p4中,有人读

给定一个声明区域中的一组声明,每个声明都指定相同的非限定名称, - (4.1)它们都应引用同一个实体......

天真的阅读可能意味着以下代码可能有效,因为"两个声明都引用同一个实体":

int x;
int x;
Run Code Online (Sandbox Code Playgroud)

然后可能会记住一个定义规则[basic.def.odr] p1.上述推理可能仅适用于不是定义的声明.区别在[basic.def] p2中详细说明.例如,以下代码肯定是有效的:

extern int x;
extern int x;
Run Code Online (Sandbox Code Playgroud)

[basic.def] p2中的最后一个示例表明以下代码应该有效,但它不能编译(使用MSVC2015).

struct B
{
    int y;
};

struct D : B
{
    using B::y;
    using B::y;
};
Run Code Online (Sandbox Code Playgroud)

问题出在哪儿?


错误消息是

'B :: y'的using声明不能与'B :: y'的现有using声明共存

c++ language-lawyer c++11

4
推荐指数
1
解决办法
1054
查看次数

C++类名注入

根据标准[class]/2:

...类名也插入到类本身的范围内; 这被称为注入类名....

而且,[basic.scope.pdecl]/9:

注入类名(第9条)的声明点紧跟在类定义的开头括号之后.

最后,[basic.lookup.classref]/3及其示例:

如果unqualified-id是~ type-name,则查找type-name ...

struct A { };
struct B {
    struct A { };
    void f(::A* a);
};
void B::f(::A* a) {
    a-> ~ A(); // OK: lookup in *a finds the injected-class-name
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,我们可以收集:

  1. 在A类的范围内,存在名称A.
  2. 该名称在A类定义括号的开头声明.
  3. 该名称命名一种类型.

如果以上是正确的,那么为什么以下代码无法编译(在MSVC2015中):

struct inj
{};

typedef struct inj::inj inj2;
Run Code Online (Sandbox Code Playgroud)

错误消息

错误C2039'{ctor}':不是'inj'的成员

似乎与标准不一致:

注意:例如,构造函数在详细类型说明符中不是可接受的查找结果,因此不会使用构造函数来代替inject-class-name. - 注意

c++ language-lawyer c++11

4
推荐指数
1
解决办法
541
查看次数

为什么枚举类的默认类型与枚举的基础类型不同?

我问为什么以下代码在Visual Studio 2014更新4中产生错误.

enum A
{   a = 0xFFFFFFFF };

enum class B
{   b = 0xFFFFFFFF };
Run Code Online (Sandbox Code Playgroud)

我知道我可以用enum class B : unsigned int.但是为什么默认底层类型enum的默认底层类型是默认的底层类型enum class?应该有一个设计决定.


澄清 我忘了提到错误:

错误C3434:枚举器值'4294967295'不能表示为'int',值为'-1'

这表明默认的底层类型enum classsigned int默认类型enumis unsigned int.这个问题是关于标志部分.

c++ c++11

3
推荐指数
2
解决办法
5341
查看次数

C++ 类声明中的限定名称

根据此页面,类名可以是“可选限定的”。因此,我希望编译以下代码:

struct ::globalSt {};
Run Code Online (Sandbox Code Playgroud)

在 MSVC 2013u4 中,我收到错误:

错误 1 ​​错误 C2039:“globalSt”:不是“全局命名空间”的成员

我是否误解了参考文献,或者这是 MSVC 的错误?

c++ struct visual-c++ msvc12

3
推荐指数
1
解决办法
2357
查看次数

什么是函数的参考限定符?

根据该网页,非静态成员函数可以具有尾随&或其&&声明.他们有以下例子

struct S {
    virtual int f(char) const, g(int) &&; // declares two non-static member functions
    };
Run Code Online (Sandbox Code Playgroud)

1)第二个功能的签名是否包括virtual

virtual int g(int) &&
Run Code Online (Sandbox Code Playgroud)

2)尾随的含义是&&什么?

c++ c++11

3
推荐指数
1
解决办法
585
查看次数

typedef中同义词的含义

以下段落摘自 [dcl.typedef]:

在其声明的范围内,typedef-name 在语法上等效于关键字,并以第 8 条中描述的方式命名与标识符关联的类型。因此 typedef-name 是另一种类型的同义词。typedef-name 不会像类声明 (9.1) 或枚举声明那样引入新类型。

我们需要的另一个相关段落来自 [dcl.type]

作为一般规则,在声明的完整声明说明符序列中或在类型说明符序列或尾随类型说明符序列中最多允许一个类型说明符。此规则的唯一例外如下:…… long 可以与 long 组合。

在下面的代码中,i1long 只是同义词。

typedef long i1;
typedef long i1 i2;
Run Code Online (Sandbox Code Playgroud)

因此,我希望将第二行理解为typedef long long i2. 但是,MSVC2015RC 失败了

错误 C2146 语法错误:缺少“;” 在标识符“i2”之前

任何人都可以指出标准中使我的期望无效的部分吗?


更新

我的观点是,据我了解 [dcl.type] 中的语法,

type-specifier:
    trailing-type-specifier
    class-specifier
    enum-specifier
trailing-type-specifier:
    simple-type-specifier
    elaborated-type-specifier
    typename-specifier
    cv-qualifier
type-specifier-seq:
    type-specifier attribute-specifier-seq opt
    type-specifier type-specifier-seq
trailing-type-specifier-seq:
    trailing-type-specifier attribute-specifier-seq opt
    trailing-type-specifier trailing-type-specifier-seq
Run Code Online (Sandbox Code Playgroud)

声明说明符序列确实允许一系列类型说明符,只要它们满足组合规则。在我看来,即使类型是由类型说明符指定的,类型也与类型说明符不同;-)

c++ standards c++11

3
推荐指数
1
解决办法
542
查看次数

C++名称查找 -

标准说(括号我的)

在3.4.1 [非限定名称查找]中列出的所有情况下,将按照每个相应类别中列出的顺序搜索范围...

为什么这些名字会被保存在某种有序列表中?毕竟,除了函数重载和名称隐藏之外,我认为名称在名称空间中是唯一的.


更新以发表评论:

我希望编译器保持在容器中定义的名称,例如每个范围的unordered_set和在查找链中链接的范围.

我想知道为什么名称会被分类为每个类别的列表(我认为是变量,typedef,结构类似,函数,模板等),并且这些列表进一步排序.

c++ language-lawyer

3
推荐指数
1
解决办法
79
查看次数

是否有引用的typeid?

我正在寻找一种获取类型名称的方法,类似于typeid引用.根据此页面,typeid删除参考.

如果type是引用类型,则结果引用引用的类型.

我正在寻找类似的代码

int x = 5;
int & y = x;
wcout << typeid( y ).name();
Run Code Online (Sandbox Code Playgroud)

但其输出是"int&"而不是"int".

c++ types type-conversion c++11

2
推荐指数
2
解决办法
1380
查看次数

在静态库中包含STL

我创建了一个静态库,下面是alien.h和alien.cpp文件.该库由user.cpp文件链接.如果删除带注释的行,则代码将按预期编译,链接和运行.实际上,库和程序编译,但程序没有链接.MSVC2015RC会生成超过100个std::numeric_limits已定义的错误.

是否有一些我应该注意的设置或者这是一个MSVC2015错误?

文件alien.h

#include <vector> // This line causes troubles.

struct alien
{
    const int * const value;
};

extern alien meh;
Run Code Online (Sandbox Code Playgroud)

文件alien.cpp

alien meh { 7 };
Run Code Online (Sandbox Code Playgroud)

文件user.cpp

#include "alien.h"
#include <iostream>
#pragma comment(lib, "alien.lib")

int main()
{
    wcout << meh.value;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

错误LNK2005"public:static int const std :: numeric_limits :: max_exponent"(?max_exponent @?$ numeric_limits @ M @ std @@ 2HB)已在alien.obj中定义

c++ stl static-libraries c++11

2
推荐指数
1
解决办法
683
查看次数

未记录的C ++预处理程序指令(MSVC 2013u4)

在MS文件apiset.h中,有以下预处理程序指令:

#define API_SET_BY_ORDINAL(X,O,PO)         X @##O NONAME
Run Code Online (Sandbox Code Playgroud)

MS 帮助页面可识别字符串化,字符化和令牌粘贴预处理器命令。'@'不是96个可接受的字符之一,在MSVC中,'##'之前的'@'不能在标识符中。

整个'@ ##'是预处理程序命令吗?如果是这样,其目的是什么?如果没有,应该如何理解上面的宏?

c++ c-preprocessor

1
推荐指数
1
解决办法
188
查看次数