小编sp2*_*nny的帖子

如何解决悬空的 const ref

以下短节目

#include <vector>
#include <iostream>

std::vector<int> someNums()
{
    return {3, 5, 7, 11};
}

class Woop
{
public:
    Woop(const std::vector<int>& nums) : numbers(nums) {}
    void report()
    {
        for (int i : numbers)
            std::cout << i << ' ';
        std::cout << '\n';
    }
private:
    const std::vector<int>& numbers;
};

int main()
{
    Woop woop(someNums());
    woop.report();
}
Run Code Online (Sandbox Code Playgroud)

有一个悬空引用问题,似乎没有编译器警告过。问题是临时文件可以绑定到 const-refs,然后您可以保留它。那么问题是;有没有办法避免陷入这个问题?最好是不涉及牺牲常量正确性或总是制作大对象的副本。

c++

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

标准容器的例外要求

C++11§23.2.1.10规定:

除非另有说明,否则本条款中定义的所有容器类型均满足以下附加要求:

  • 如果插入单个元素时insert()或emplace()函数抛出异常,则该函数不起作用.
  • 没有erase(),clear(),pop_back()或pop_front()函数抛出异常.

关于第一个要点,容器如何保证?构造函数T可能有副作用.它不应该" 对容器没有影响 "

关于第二个要点,这通常称为allocator::deallocate(T*,size_t)不是noexcept.为什么最终的异常会被掩盖?

c++ language-lawyer c++11

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

Clang格式.如何在交换机中获取单行对齐的case语句

我希望clang格式如下:

switch (x)
{
case long_name: return 1;
case sn:        return 2;
}
Run Code Online (Sandbox Code Playgroud)

AllowShortCaseLabelsOnASingleLine选项将它们放在同一行,
但我还没有找到一种方法来使语句对齐.

c++ clang-format

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

使用带有unique_ptr的自定义删除器

使用shared_ptr,您可以使用自定义删除器,例如:

auto fp = shared_ptr<FILE>( fopen("file.txt", "rt"), &fclose );
fprintf( fp.get(), "hello\n" );
Run Code Online (Sandbox Code Playgroud)

fclose无论函数如何退出,这都将记住该文件.
但是,重新计算局部变量似乎有点过分,所以我想使用unique_ptr:

auto fp = unique_ptr<FILE>( fopen("file.txt", "rt"), &fclose );
Run Code Online (Sandbox Code Playgroud)

但是,这不会编译.

这是一个缺陷吗?有一个简单的解决方法吗?我错过了一些微不足道的东西?

c++ smart-pointers

10
推荐指数
3
解决办法
5695
查看次数

以价值取决于谓词

标准库中的各种容器按值来获取谓词.

例如:

从§23.3.5开始 std::list

template <class Predicate>
void remove_if(Predicate pred);
Run Code Online (Sandbox Code Playgroud)

将谓词作为转发引用是否有优势?
它可能不是那么常见,但可能是仿函数很难复制.
一般的推荐是按值来判断谓词,在这种情况下为什么?

c++

8
推荐指数
0
解决办法
183
查看次数

首选包含std :: size_t的标头

std::size_t 在以下任何一个中定义:
<cstddef> <cstdio> <cstdlib> <cstring> <ctime> <cwchar>

刚才被认为是"犹太人" std::size_t

c++

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

gcc中的错误,或clang/MSVS中的扩展

以下代码段在clang和MSVS中编译,但不在gcc中编译.

template<typename T> class clone_ptr;

template<typename T, typename U, typename ...Args>
clone_ptr<T> make_cloned( Args ...args );

// note: everything not needed for example cut out, so
// this class is neither complete nor correct
template<typename T>
class clone_ptr 
{
public:
    clone_ptr() : ptr(nullptr) {}
    operator bool() { return ptr!=nullptr; }
    T* operator->() { return ptr; }
private:
    clone_ptr(T* p) : ptr(p) {}
    T* ptr;

    template<class T1,class U1, typename ...Args>
        friend clone_ptr<T1> make_cloned( Args ...args );
};

template<typename T, typename U=T, …
Run Code Online (Sandbox Code Playgroud)

c++ variadic-templates

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

constexpr初始化应该在其他初始化之前发生

我有以下代码,在gcc和clang上表现得如预期的那样.但是,MSVC给了我一个意想不到的结果.

让我们先看看有问题的代码.

#include <iostream>

// -----------------------------------------------

class Test // Dummy for MCVE
{
public:
    Test();
    void Print();
private:
    int arr[5];
};

Test tst;

// -----------------------------------------------

template<typename T>
struct range // some stuff not needed by example removed
{
    constexpr range(T n) : b(0), e(n) {}
    constexpr range(T b, T e) : b(b), e(e) {}
    struct iterator
    {
        T operator*() { return i; }
        iterator& operator++() { ++i; return *this; }
        bool operator!=(iterator other) { return i != other.i ; } …
Run Code Online (Sandbox Code Playgroud)

c++

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

什么时候异常对象被破坏(并且可以被控制)?

我正在为容器编写一个drop-replacement,我正在努力获得所有异常保证.我正在编写该clear方法,我希望它尽可能地完成,并始终将容器保持在一致状态,即使其中一个析构函数抛出异常.我也想在清洁完毕后重新抛出异常,最好不要切片.

这让我想到了这个问题; 什么时候被破坏了?让我们看一下尝试:这个例子简化了.

void container::clear()
{
    bool had_exception = false;
    std::exception* exp;
    internal_set_empty(); // this cant throw
    while( ! internal_done() )
    {
        try
        {
            internal_destruct_next(); // this might throw if T::~T() throws
        }
        catch( std::exception& e )
        {
            had_exception = true;
            exp = &e;
        }
    }
    if( had_exception )
        throw *exp;
}
Run Code Online (Sandbox Code Playgroud)

我希望这会严重失败,因为异常可能在被认为是被处理时被破坏,这在技术上不会重新抛出.

另一个尝试是获取异常的副本,我期望切片.

有没有办法延长异常的生命周期,以便稍后重新抛出它?如果可能的话,我也希望能够重新抛出通过的异常catch(...).

c++

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

c++23 断不动吗

标准中有关隐式移动的措辞在 c++23 中发生了变化,
请参阅https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2266r3.html
相关部分是:

返回的符合移动条件的 id 表达式始终是 xvalue

这似乎打破了流行但不明智的“不动”

template<typename T>
auto unmove(T&& v) -> std::remove_reference_t<T>& { return v; }
Run Code Online (Sandbox Code Playgroud)

当前的实现似乎同意:https ://godbolt.org/z/3n39rGM7b

这个重大改变是有意为之的,还是我们可以期待灾难恢复?

c++ language-lawyer c++23

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