小编Ale*_*104的帖子

const 是否被 std::views 破坏了?

void foo(const auto& collection)
{
    *collection.begin() = 104;
}

int main()
{
    std::vector<int> ints {1, 2, 3, 4, 5};
    foo(ints); // Error, as it should be
    foo(ints | std::views::all); // Compiles and modifies the vector. Why?
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果函数的参数是类型,为什么左值引用的常量性会被完全忽略std::view

编辑:
如果,正如您在注释中所写,const 视图引用与此上下文中的 const 指针类似,那么如果同一函数采用从右值对象构造的视图作为参数,为什么代码无法编译?

std::vector<int> getVec()
{
    return std::vector{1, 2, 3, 4, 5};
}

void foo(const auto& collection)
{
    *collection.begin() = 104; // Error: assignment of read-only location
}

int main()
{
    foo(getVec() | std::views::all); // Nope! …
Run Code Online (Sandbox Code Playgroud)

c++ constants c++20 std-ranges

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

如果我故意标记一个函数[我知道可能会抛出] noexcept 以在发生异常时立即终止,我的代码是否格式不正确?

我知道,标记一个函数noexcept可能有助于[在某些情况下]获得许多很棒的优化,例如移动语义。但是假设,我的代码中有一个函数执行非常关键的操作,如果该函数失败,则意味着发生了非常糟糕的事情以至于无法恢复,并且该程序应该立即终止。如果我故意标记这样一个函数,noexcept即使我承认有异常的可能性,只是为了在发生异常时杀死程序怎么办?

有些东西告诉我这不是它应该使用的用途,但它是 的有效用途吗noexcept

c++ noexcept

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

noexcept 对显式默认的移动构造函数/赋值运算符有影响吗?

class C
{
    public:
        C(C&&) = default; // (1)
        C& operator=(C&&) = default; // (1)

        C(C&&) noexcept = default; // (2)
        C& operator=(C&&) noexcept = default; // (2)
}
Run Code Online (Sandbox Code Playgroud)

据我所知,如果移动构造函数/赋值运算符是由用户隐式生成或显式默认的(1),编译器将noexcept根据类的所有成员是否noexcept为移动操作提供保证来决定是否应该使用这些特殊成员函数。但是,如果我想使用默认移动特殊成员并强制它们不noexcept考虑移动操作的底层成员异常保证,该怎么办?(1)和声明之间的编译器有什么区别吗(2)

c++ move-semantics noexcept

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

在类的方法中重新分配 *this 是否安全?

我有一个与磁盘上存储的某些文件相关的对象。该对象的构造函数接受该文件作为参数,读取它并根据文件内容的设置创建一个实际对象。在运行时该文件有可能被用户修改。该对象有一个方法来检查文件自上次读取以来是否已被修改,如果是这样,则必须更新该对象。对象内部有足够的成员需要更新,因此无需手动更新每个成员,只需创建一个新对象并将其移动到现有对象中会更方便(更少的键入和更好的可读性)。*this但在方法执行期间进行更改实际上是否安全,如下例所示?

void Object::update()
{
    if (this->isModified(file)) // Check if a file has been modified since the last read
    {
        try
        {
            Object newObject(file); // May throw
            *this = std::move(newObject); // Is it safe?
        }
        catch (const std::exception& ex)
        {
            // Invalidate and rethrow exception
            this->invalidate();
            throw(ex);
        }
    }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

c++ this-pointer

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

为已移出的对象分配新值并进一步使用该对象是否安全?

std::string str1{"This is a test string"};
std::string str2{std::move(str1)};
str1 = "This is a new content of this string";
// Use str1...
Run Code Online (Sandbox Code Playgroud)

我是否正确地认为str1现在处于有效状态并且在为其分配新值后可以完全安全地使用?

c++ move-semantics

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

缓存视图对象内部会导致UB?

#include <iostream>
#include <vector>
#include <ranges>

int main()
{
    std::vector<int> ints {1, 2, 3, 4, 5};
    auto isEven = [] (const auto& element)
    {
        return element % 2 == 0;
    };
    auto even = ints | std::views::filter(isEven);
    for (auto& element : even)
    {
        ++element;
    }
    for (const auto& element : ints)
    {
        std::cout << element << "\n";
    }
    std::cout << "\n\n";
    
    // Interesting things start further...
    for (auto& element : even)
    {
        ++element;
    }
    for (const auto& element : ints) …
Run Code Online (Sandbox Code Playgroud)

c++ c++20 std-ranges

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

是否可以在 main() 之外调用函数?

我想我的问题很愚蠢,但尽管如此:

在我的 C++ 代码中,我使用一些遗留的 C 库(XLib)。为了使用这个库,必须首先打开到 X 服务器的连接:

::Display* const display = ::XOpenDisplay(nullptr);
Run Code Online (Sandbox Code Playgroud)

这种display结构广泛用于绝大多数 XLib 函数,包括分配和释放内存和系统资源(如字体、颜色图等)的函数。在我的代码中,我使用对象的构造函数和析构函数通过调用这些函数来分配和释放资源功能。问题是这样的:

int main()
{
    ::Display* const display = ::XOpenDisplay(nullptr);
    // ...
    Object1 object1(display, ...); // uses display inside the destructor
    Object2 object2(display, ...); // uses display inside the destructor
    Object3 object3(display, ...); // uses display inside the destructor
    // ...
    ::XCloseDisplay(display); // invalidates the display structure
    return 0;
}

Run Code Online (Sandbox Code Playgroud)

此示例会导致分段错误,因为在调用任何使用该结构的析构函数之前该display结构已失效。XCloseDisplay()为了避免这个问题,我可以将之前的所有代码放在XCloseDisplay()大括号中以限制对象的范围,但这会使代码向右移动,这看起来非常难看。

有什么办法可以XCloseDisplay()在之后打电话main()吗?

c++ destructor scope

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