小编Ser*_*uin的帖子

dynamic_cast和rvalue引用

class A{
public:
    virtual ~A() {};
};

class B : public A{ };

int main(){

    A&& p = B();

    dynamic_cast<B&&>(std::move(p));

}
Run Code Online (Sandbox Code Playgroud)

抛出错误(g ++ 5.2.0):

error: conversion to non-const reference type 'std::remove_reference<A&>::type& {aka class A&}' from rvalue of type 'A' [-fpermissive]
Run Code Online (Sandbox Code Playgroud)

它试图转换std::move(p)为类型A&,但我无法弄清楚为什么.我会一直认为有必要投p转换为右值引用之前作为右值,但如果我删除std::move它编译罚款.从cppreference:

dynamic_cast < new_type > ( expression )

与其他强制转换表达式类似,结果如下:

如果new_type是左值引用类型(表达式必须是左值),则为左值

如果new_type是右值引用类型(表达式可能是左值或右值),则为xvalue

甚至是N3337的5.2.7:

dynamic_cast<T>(v)

如果T是指针类型,则v应该是指向完成类类型的指针的prvalue,结果是类型T的prvalue.如果T是左值引用类型,则v应该是完整类类型的左值,并且结果是由T 引用的类型的左值.如果T是右值引用类型,则v应该是具有完整类类型的表达式,并且结果是由T引用的类型的x值.

唯一要求我使用完整的类类型,std::move(p)不是吗?

c++ dynamic-cast rvalue language-lawyer c++11

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

向try块本地抛出一个数组

来自C++ Primer 18.1.1:

如果[thrown]表达式具有数组或函数类型,则表达式将转换为其对应的指针类型.

该程序如何产生9876543210(g ++ 5.2.0)的正确输出?

#include <iostream>
using namespace std;

int main(){

    try{
        int a[10] = {9,8,7,6,5,4,3,2,1,0};
        throw a;
    }
    catch(int* b) { for(int i = 0; i < 10; ++i) cout << *(b+i); }

}
Run Code Online (Sandbox Code Playgroud)

从引用中,throw a将创建一个类型的异常对象,int*它是指向数组的第一个元素的指针.但是a当我们退出try块并输入catch子句时,我们肯定会破坏数组元素,因为我们改变了块范围?在catch子句的持续时间内,我是否得到了误报或数组元素"单独留下"(未删除)?

c++ arrays throw c++11

14
推荐指数
3
解决办法
558
查看次数

尽管没有定义<new>标头,但新抛出bad_alloc?

如果没有(因为标题中定义了这个错误),new程序中的表达式如何抛出错误怎么回事?bad_alloc#include <new><new>

从3.7.4开始.N3337:

该库提供全局分配和释放功能的默认定义.一些全局分配和释放功能是可替换的(18.6.1).C++程序最多只能提供一个可替换分配或释放功能的定义.任何此类函数定义都将替换库中提供的默认版本(17.6.4.6).以下分配和释放函数(18.6)在程序的每个转换单元中在全局范围中隐式声明.

void* operator new(std::size_t);

void* operator new[](std::size_t);

void operator delete(void*);

void operator delete[](void*);
Run Code Online (Sandbox Code Playgroud)

这些隐含的声明只介绍了函数名operator new,operator new[],operator delete,和operator delete[].[ 注:隐式声明不引入名称std,std::size_t或该库使用来声明这些名称的任何其他名称.因此,在不包括头部的情况下引用这些函数之一的新表达式,删除表达式或函数调用<new>是格式良好的.但是,除非通过包含适当的标题声明了名称,否则引用stdstd::size_t形成不良.-end note ]也可以为任何类声明和定义分配和/或释放函数

这仍然不清楚.隐式声明使用std::size_t但不引入它们(同样必须是这样bad_alloc)?并且std::size_tnew表达式可以使用之前不需要引入?可以理解这是怎么回事,或者我必须从表面上看它?

c++ bad-alloc c++11

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

使用shared_ptr处理不完整类型的Pimpl习惯用法

我正在阅读Scott Meyers撰写的Effective Modern C++,他正在讨论使用pimpl习语并指向实现类unique_ptr,但是存在需要完整类型的特殊成员函数(例如析构函数)的问题.这是因为unique_ptrdelete p使用之前,默认删除器静态断言要删除的类型是否完整.所以任何类特殊的成员函数必须在实现文件中定义(而不是编译器生成的),之后实现类已定义.

在本章的最后,他提到如果使用的是智能指针,则不需要在实现文件中定义特殊的成员函数shared_ptr,这源于它支持自定义删除器的方式.报价:

pImpl指针的std :: unique_ptr和std :: shared_ptr之间的行为差​​异源于这些智能指针支持自定义删除器的不同方式.对于std :: unique_ptr,删除器的类型是智能指针类型的一部分,这使编译器可以生成更小的运行时数据结构和更快的运行时代码.这种更高效率的结果是,当使用编译器生成的特殊函数(例如,析构函数或移动操作)时,指向类型必须是完整的.对于std :: shared_ptr,删除器的类型不是智能指针类型的一部分.这需要更大的运行时数据结构和稍慢的代码,但是当使用编译器生成的特殊函数时,指向的类型不需要完整.

尽管如此,我仍然不明白为什么shared_ptr没有完成课程仍然可以工作.这似乎是使用时没有编译器错误的唯一原因shared_ptr是因为没有像has那样的静态断言unique_ptr,并且由于缺少断言而可能会发生未定义的运行时行为.

我不知道shared_ptr析构函数的实现,但是(从阅读C++ Primer)我收集的印象它的工作原理如下:

del ? del(p) : delete p;
Run Code Online (Sandbox Code Playgroud)

del自定义删除器的指针或函数对象在哪里.Cppreference还清楚地说明shared_ptr了没有自定义删除器使用的析构函数delete p

3)delete ptr如果T不是数组类型,则使用delete-expression ; .... Y必须是完整的类型.删除表达式必须格式正确,具有明确定义的行为并且不会抛出任何异常.

强调删除类型必须完整的事实.pimpl习语的最小例子:

//widget.h

#ifndef WIDGET
#define WIDGET

#include <memory>

class Widget{
public:
    Widget();
private:
    struct Impl;
    std::shared_ptr<Impl> pImpl;

};

#endif // …
Run Code Online (Sandbox Code Playgroud)

c++ pimpl-idiom smart-pointers c++11

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

Hexfloat机械手和精度

为什么使用hexfloat操纵器的输出会忽略任何精度ostream

#include <iostream>
#include <cmath>
#include <iomanip>

using namespace std;

int main(){

    cout << setw(17) << left << "default format: " << setw(20) << right << 100 * sqrt(2.0) << " " <<  cout.precision() << '\n'
         << setw(17) << left << "scientific: " << setw(20) << right << scientific << 100 * sqrt(2.0) << " " <<  cout.precision() <<  '\n'
         << setw(17) << left << "fixed decimal: " << fixed << setw(20) << right << 100 …
Run Code Online (Sandbox Code Playgroud)

c++ precision hex c++11

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