是否修改 const 对象的内部字节未定义行为,以防它包含由放置 new 构造的另一个对象?

Tar*_*ras 8 c++ standards placement-new undefined-behavior

考虑以下示例:

#include <new>

struct FunctionObject
{
    int operator()() // non-const, modifies the state of this object
    {
        i += 1;
        j += 2;
        return i + j;
    }

    int i = 0;
    int j = 0;
};

struct Wrapper
{
    explicit Wrapper(const FunctionObject& input_object)
    {
        constructed_object = ::new (buffer) FunctionObject(input_object);
    }

    ~Wrapper()
    {
        constructed_object->~FunctionObject();
    }

    int operator()() const // const, but invokes the non-const operator() of the internal FunctionObject
    {
        return (*constructed_object)(); // this call modifies the internal bytes of this Wrapper
    }

    alignas(FunctionObject) unsigned char buffer[sizeof(FunctionObject)];
    FunctionObject* constructed_object = nullptr;
};

int test()
{
    const FunctionObject function_object{3, 4};
    const Wrapper object_wrapper{function_object}; // this call modifies the internal bytes of a const Wrapper
    return object_wrapper();
}
Run Code Online (Sandbox Code Playgroud)

A Wrapper contains an internal FunctionObject which is constructed inside the Wrapper by a placement new.

The Wrapper object is const, its operator() is also const, but calling it causes the internal state of the object to be modified. In many cases, similar scenarios are undefined behavior in C++.

The question is, is it undefined behavior in this particular case (~ do I need to mark the buffer as mutable?), or does the C++ standard allow writing code like this?

120*_*arm 4

这是未定义的行为。

来自[dcl.type.cv],

在 const 对象的生命周期内任何修改 const 对象的尝试都会导致未定义的行为。

添加mutable说明符buffer将允许它被const成员函数修改。