2016-07-23 16 views
5

Có cách nào để chúng tôi có thể sử dụng chức năng thành viên đủ điều kiện với std::mem_fn không?std :: mem_fn với chức năng thành viên ref_qualified

Mã dưới đây không biên dịch: Thông điệp

class DeadPool { 
public: 
    void jump() & { 
    std::cout << "Did not jump\n"; 
    } 

    void jump() && { 
    std::cout << "Jumped from helicopter\n"; 
    } 
}; 

int main() { 
    DeadPool dp1; 
    //auto cobj = std::mem_fn(&DeadPool::jump); // Won't compile 
    //cobj(dp1); 
    //cobj(DeadPool()); 
    using Func = void (DeadPool::*)() &; // lvalue ref qualifier explicitly provided 
    Func fp = &DeadPool::jump; // This works, as expected 
    (std::move(dp1).*fp)(); 
    return 0; 
} 

Lỗi:

mem_fn_ex.cc:18:15: error: no matching function for call to 'mem_fn'
auto cobj = std::mem_fn(&DeadPool::jump); // Won't compile ^~~~~~~~~~~ /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/functional:1233:1: note: candidate template ignored: couldn't infer template argument '_Rp' mem_fn(_Rp _Tp::* __pm)^mem_fn_ex.cc:23:18: error: pointer-to-member function type 'Func' (aka 'void (DeadPool::*)() &') can only be called on an lvalue (std::move(dp1).*fp)(); ~~~~~~~~~~~~~~^

Compiler: Trên cả Clang (3.4) và g ++ (5.3)

tôi nghĩ rằng tôi có thể làm cho sử dụng thực tế rằng, trong việc thực hiện lớp học std::_Mem_fn một đối tượng giá trị được gọi như sau:

return (std::move(__object).*__pmf)(std::forward<_Args>(__args)...); 

Điều này có thể đã gọi rất tốt chức năng thành viên cụ thể cho rvalue this, nhưng vì chữ ký khác với thời gian biên dịch nên không thể thực hiện điều đó.

Trả lời

4

Vấn đề là bạn đang chuyển hàm bị quá tải vào mẫu chức năng - mem_fn() không thể suy ra jump() bạn muốn. Bạn sẽ cần phải vượt qua một cụ thể với một dàn diễn viên:

auto cobj = std::mem_fn(static_cast<void (DeadPool::*)() &>(&DeadPool::jump)); 
cobj(dp1);  // ok 
cobj(DeadPool()); // error 

Tuy nhiên, đó là một giải pháp thực sự không thỏa mãn do cả hai tính cách rườm rà (đó là một LOT gõ) và những hạn chế (bạn có & - và && -qualified quá tải cho một lý do, nhưng bạn chỉ có thể sử dụng một?). Tốt hơn để sử dụng lambda chung tại đây:

auto jump = [](auto&& pool){ std::forward<decltype(pool)>(pool).jump(); }; 
jump(dp1);   // ok: Did not jump 
jump(DeadPool()); // ok: Jumped from helicopter 
+0

Điều này khiến tôi nghĩ tại sao 'này' không bị quá tải dựa trên vòng loại ref thay thế. Bất kỳ ý tưởng ? – Arunmu

+0

@Arunmu Điều đó có liên quan gì đến câu hỏi này? – Barry

+0

Vâng, nếu trình biên dịch thực hiện nó theo cách đó, mã trong câu hỏi có thể đã làm việc. – Arunmu

Các vấn đề liên quan