std :: chức năng const chính xác


11

Giả sử tôi có một loại có thể gọi như vậy:

struct mutable_callable
{
    int my_mutable = 0;
    int operator()() { // Not const
        return my_mutable++;
    }
};

Lưu ý rằng mutable_callablecó một hằng số operator()sửa đổi một biến thành viên .....

Bây giờ giả sử tôi tạo ra một std::functionloại của tôi:

std::function<int()> foo = mutable_callable{};

Bây giờ tôi có thể làm điều này:

void invoke(std::function<int()> const& z)
{
    z();
}

int main()
{
    invoke(foo); // foo changed.....oops
}

Bây giờ như xa như tôi có thể nói với std::functions operator()consttheo: https://en.cppreference.com/w/cpp/utility/functional/function/operator ()

Vì vậy, cảm giác ruột của tôi là bạn không nên làm điều này .....

Nhưng sau đó nhìn vào: https://en.cppreference.com/w/cpp/utility/feftal/feft/feft

Điều này dường như không đặt ra bất kỳ ràng buộc nào về việc loại có thể gọi được có hằng số hay không operator()......

Vì vậy, câu hỏi của tôi là: Tôi đúng khi cho rằng std::function<int()> const&về cơ bản là giống như std::function<int()>&điều đó thực sự không có sự khác biệt giữa hành vi của hai người ...... và nếu đó là trường hợp tại sao nó không constđúng?


@MaxLanghof Không ..... std::functioncó tương đương với a struct a{ std::any x; };trong đó .....
DarthRubik

Đây là một đoạn nhỏ về nội bộ của việc std::functionthực hiện MSVC : i.stack.imgur.com/eNenN.png ở đâu using _Ptrt = _Func_base<_Ret, _Types...>. I nghỉ ngơi trường hợp của tôi.
Max Langhof

Câu trả lời:


3

Điều này sôi xuống giống như struct A { int* x; };, trong đó const A a;bạn có thể sửa đổi giá trị của *(a.x)(nhưng không phải là nơi nó trỏ đến). Có một mức độ gián tiếp trong std::function(từ kiểu xóa) thông qua đó constkhông được truyền bá.

Và không, std::function<int()> const& fkhông phải là vô nghĩa. Trong một std::function<int()>& fbạn sẽ có thể chỉ định một functor khác f, mà bạn không thể làm trong consttrường hợp này.


Yup ..... điều đó thực sự rất có ý nghĩa ..... mặc dù thoạt nhìn vẫn khó hiểu
DarthRubik

Tôi tin rằng đó là một lỗ hổng thiết kế. Hướng dẫn này phải là một chi tiết triển khai minh bạch cho người dùng và hằng số có thể được truyền bá bằng cách sử dụng một số siêu lập trình.
Igor R.

@IgorR. Vâng, các hằng số có thể được tuyên truyền. std::vectorlàm điều này, std::unique_ptrkhông. Tôi cảm thấy std::functionkhông thực sự về việc thể hiện bất biến của trạng thái functor. Có lẽ chúng ta có thể tái sử dụng các loại hàm gớm ghiếc (tức là std::function<int() const>) để phân biệt?
Max Langhof

unique_ptrkhông nên tuyên truyền hằng, như con trỏ thông thường không. Và std::function<int() const>sẽ không biên dịch.
Igor R.

@IgorR. Tôi biết. Quan điểm của tôi là một số phần của thư viện tiêu chuẩn làm điều đó và một số phần khác thì không. Những loại std::functionnên rơi vào không rõ ràng với tôi. Và đó std::function<int() const>là một giả thuyết - tất nhiên bây giờ nó không được biên dịch, nhưng liệu nó có thỏa mãn hay không, ví dụ như OP ở đây nếu điều đó có thể hợp lệ, thể hiện "chỉ có thể được gán functor với một operator() const(hoặc không trạng thái)"? (ngay cả khi đằng sau hậu trường sẽ khá tàn bạo, do sử dụng các loại chức năng gớm ghiếc)?
Max Langhof
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.