std :: ฟังก์ชั่น const ความถูกต้อง


11

สมมติว่าฉันมีประเภท callable ดังนี้

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

โปรดทราบว่าmutable_callableมีไม่ใช่operator()สมาชิกที่แก้ไขตัวแปรสมาชิก .....

ตอนนี้สมมติว่าฉันสร้างstd::functionประเภทของฉัน:

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

ตอนนี้ฉันสามารถทำสิ่งนี้:

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

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

ตอนนี้เท่าที่ผมสามารถบอกได้std::functions operator()เป็นconstตาม: https://en.cppreference.com/w/cpp/utility/functional/function/operator ()

ดังนั้นความรู้สึกของฉันคือคุณไม่ควรทำสิ่งนี้ .....

แต่จากนั้นดูที่: https://en.cppreference.com/w/cpp/utility/functional/function/function

ดูเหมือนว่านี่จะไม่มีข้อ จำกัด ใด ๆ กับชนิด callable ที่มีค่าคงที่operator()......

ดังนั้นคำถามของฉันคือ: ฉันถูกต้องในการสมมติว่าstd::function<int()> const&เป็นสิ่งเดียวกับstd::function<int()>&ที่ไม่มีความแตกต่างระหว่างพฤติกรรมของทั้งสอง ...... และถ้าเป็นกรณีที่ว่าทำไมมันไม่constถูกต้อง?


@ MaxLanghof ไม่ ..... std::functionมีสิ่งที่เทียบเท่ากับstruct a{ std::any x; };มันอยู่ในนั้น .....
DarthRubik

นี่คือตัวอย่างเล็ก ๆ ของ internals ของ MSVC std::functionการดำเนินงาน: i.stack.imgur.com/eNenN.pngusing _Ptrt = _Func_base<_Ret, _Types...>ที่ ฉันพักกรณีของฉัน
Max Langhof

คำตอบ:


3

สิ่งนี้จะทำให้เดือดลงไปเช่นเดียวกับstruct A { int* x; };ในกรณีที่const A a;คุณสามารถปรับเปลี่ยนค่าของ*(a.x)(แต่ไม่ใช่ตำแหน่งที่ชี้ไป) มีระดับของการอ้อมในstd::function(จากการลบประเภท) ซึ่งconstไม่แพร่กระจาย

และไม่std::function<int()> const& fไม่ไร้จุดหมาย ในแบบที่std::function<int()>& fคุณจะสามารถมอบหมายนักแสดงคนอื่นให้fซึ่งคุณไม่สามารถทำได้ในconstกรณีนี้


Yup ..... ที่จริงแล้วมีเหตุผลมากมาย ... ยังคงสับสนเมื่อมองแวบแรกแม้ว่า
4322

ฉันเชื่อว่ามันเป็นข้อบกพร่องในการออกแบบ ทางอ้อมนี้ควรเป็นรายละเอียดการนำไปใช้งานที่โปร่งใสให้กับผู้ใช้และความมั่นคงสามารถแพร่กระจายโดยใช้ metaprogramming บางอย่าง
Igor R.

@IgorR ใช่ความหนาแน่นอาจแพร่กระจายได้ std::vectorทำสิ่งนี้std::unique_ptrไม่ ฉันรู้สึกstd::functionไม่ได้เกี่ยวกับการแสดงค่าคงที่ของรัฐ functor บางทีเราสามารถเปลี่ยนประเภทฟังก์ชั่นที่น่ารังเกียจ (เช่นstd::function<int() const>) เพื่อแยกแยะได้
Max Langhof

unique_ptrไม่ควรเผยแพร่ความทึบเนื่องจากตัวชี้ปกติไม่ และstd::function<int() const>จะไม่รวบรวม
Igor R.

@IgorR ฉันรู้ว่า. ประเด็นของฉันคือว่าบางส่วนของห้องสมุดมาตรฐานทำและคนอื่นไม่ทำ หมวดหมู่ใดที่std::functionควรตกอยู่ในความไม่ชัดเจนสำหรับฉัน และstd::function<int() const>เป็นสมมุติ - แน่นอนมันไม่ได้รวบรวมในขณะนี้ แต่มันจะตอบสนองเช่น OP ที่นี่หากที่อาจจะทำให้ถูกต้องแสดง "functors เท่านั้นที่สามารถได้รับมอบหมายด้วยoperator() const(หรือคนไร้สัญชาติ)"? (แม้ว่าเบื้องหลังจะน่ากลัวมากเนื่องจากใช้ฟังก์ชั่นที่น่ารังเกียจ)?
Max Langhof
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.