2012-03-28 41 views
5

Tôi cố gắng để viết toán tử bool-chuyển đổi cho std :: bitsetquá tải chuyển đổi không thành viên để bool hành

tôi đã cố gắng:

template<size_t size> 
operator bool(std::bitset<size> & b) 
{ 
    return b.any(); 
} 

nhưng tôi đã nhận

error C2801: 'mynamespace::operator bool' must be a non-static member 

từ studio hình ảnh của tôi.

Nhưng khi tôi nhìn lên C2801 explanation nó nói gì về điều hành chuyển đổi (chỉ khoảng =, ->, [],())

Vì vậy, là nó có thể bằng cách nào đó viết "std :: Chuyển đổi bitset đến bool nhà điều hành?"

(Tôi không thể gọi b.any() trong tôi nếu-tuyên bố, bởi vì cùng mã phải chạy khi std :: bitset được thay thế bằng unsigned hay cái gì

typedef std::bitset<x> Bitset; 
//typedef unsigned Bitset; 

nên cú pháp lý tưởng sẽ như thế nào:

Bitset b = whatewer; 
if(b) 
    doStuff(); 

)

Nếu quá tải này là không thể, thực hiện giải pháp đề nghị là gì?

cho đến nay tôi sử dụng nó như:

if(b == Bitset(0)) 
    doStuff(); 

nhưng tôi không thích nó.

Cảm ơn bạn

+0

Đây là một câu hỏi thú vị. Tôi không biết bất kỳ cách nào trực tiếp để làm những gì bạn đề nghị. Có thể không tồn tại. Như bạn đã biết, sự cố là không phải loại được chuyển đổi cũng như loại được chuyển đổi thành người dùng được xác định. Trình biên dịch không muốn cho phép bạn thêm mới, ngụ ý chuyển đổi giữa các loại mà bạn không tạo. Bạn có thể phải định nghĩa, và gọi một cách rõ ràng, hàm của riêng bạn * make_bool(). * Ít nhất nếu bạn * inline * hàm của bạn, nó sẽ hiệu quả vào thời gian chạy như một chuyển đổi tích hợp; nhưng bạn sẽ không nhận được chuyển đổi ngầm, phải không? – thb

Trả lời

6

Như thông báo lỗi cho biết, các nhà điều hành chuyển đổi phải là một không tĩnh thành viên của một lớp. Điều đó đúng.

Tôi không thể gọi b.any() trong câu lệnh if của tôi, vì cùng mã phải chạy khi std :: bitset được thay thế bằng unsigned hoặc một cái gì đó.

Nếu đó là vấn đề của bạn, sau đó bạn có thể sử dụng chức năng quá tải, và gọi nó là đi qua các lập luận mà sẽ trả về một giá trị boolean:

template<typename T> 
bool to_bool(T const & b) 
{ 
    return b; //implicit conversion (if allowed) for all other types 
} 

template<size_t N> 
bool to_bool(std::bitset<N> const & b) 
{ 
    return b.any(); 
} 

sau đó sử dụng nó như là:

if (to_bool(whatever)) 
{ 
} 

Nó sẽ gọi quá tải chính xác. Nếu loại whateverstd::bitset<N> thì hàm quá tải thứ hai sẽ được gọi, nếu không hàm đầu tiên sẽ được gọi.

+1

Tôi đã thử làm điều này với chuyên môn hóa khi tất cả những gì tôi cần là quá tải. Điều này có vẻ ổn. –

+0

@MarkB: Có, tôi thấy rằng bạn đang thực hiện một phần chuyên môn hóa của mẫu chức năng không được phép. – Nawaz

+2

@Nawaz cảm ơn bạn rất nhiều, đây là giải pháp tốt nhất. Tôi thậm chí có thể gọi nó như 'if ((to_bool) (bất cứ điều gì))' để có được nhiều ấn tượng đúc :) cảm ơn bạn một lần nữa – relaxxx

5

§12.3.2/1: "thành viên chức năng của lớp X có tên biểu mẫu [...] chỉ định chuyển đổi từ X thành loại được chỉ định ..." (C++ 11 sử dụng cùng một số phần và gần như cùng một từ ngữ, chỉ thêm rằng hàm không có tham số).

Cách có thể khác để xác định chuyển đổi là một hàm tạo (§12.3.1), đây rõ ràng là một thành viên của lớp.

Tóm lại, có, chuyển đổi phải luôn được định nghĩa là hàm thành viên.

Một cách để làm những gì bạn muốn sẽ được để viết một wrapper xung quanh std::bitset cung cấp việc chuyển đổi mà bạn quan tâm:

template <int size> 
class mybitest { 
    std::bitset<size> bits; 
public: 
    operator bool() { return bits.any(); } 
} 

Nhưng nếu bạn quyết định làm điều đó, bạn sẽ cần phải viết các chức năng chuyển tiếp cho về cơ bản tất cả các mảnh của bitset bạn đang sử dụng (ctors, chuyển nhượng, vv)

+0

Cảm ơn bạn, câu trả lời của bạn chắc chắn là đúng, nhưng tôi sẽ đi với giải pháp Nawaz. Giải pháp của bạn là "làm việc nhiều" nhưng nó sẽ cho tôi cú pháp tôi muốn. Cảm ơn bạn một lần nữa – relaxxx

2

Tiêu chuẩn là một chút không rõ ràng về vấn đề này (12.3.2):

A chức năng thành viên của một lớp X không có tham số nào có tên của biểu mẫu [...] chỉ định chuyển đổi từ X thành loại được chỉ định theo loại chuyển đổi-id. Các hàm này được gọi là hàm chuyển đổi. Không thể chỉ định loại trả về. Nếu hàm chuyển đổi là hàm thành viên, loại hàm chuyển đổi (8.3.5) là "hàm không tham số trả về kiểu chuyển đổi-id".

Câu đầu tiên dường như ngụ ý rằng chỉ hàm thành viên có thể chức năng chuyển đổi, nhưng tôi không chắc chắn những gì mục đích của điều kiện "nếu một chức năng chuyển đổi là một hàm thành viên" này.

Tôi lấy câu đầu tiên là ràng buộc và kết luận rằng hàm chuyển đổi phải là hàm thành viên.

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