Mặc dù Boost.Thông số là thú vị, nó phải chịu đựng (không may) đối với một số vấn đề, trong đó giữ chỗ va chạm (và cần phải gỡ lỗi kỳ quặc preprocessors/mẫu lỗi):
BOOST_PARAMETER_NAME(p1)
sẽ tạo _p1
giữ chỗ mà bạn sau đó sử dụng sau này. Nếu bạn có hai tiêu đề khác nhau khai báo cùng một trình giữ chỗ, bạn sẽ gặp phải xung đột. Không vui.
Có một câu trả lời đơn giản hơn (cả khái niệm và thực tế), dựa trên mẫu Builder
phần nào là Các tham số có tên Idiom.
Thay vì chỉ định một chức năng như:
void f(int a, int b, int c = 10, int d = 20);
Bạn chỉ rõ một cấu trúc, mà trên đó bạn sẽ ghi đè lên operator()
:
- các nhà xây dựng được sử dụng để yêu cầu đối số bắt buộc (không chặt chẽ trong thành ngữ tham số được đặt tên, nhưng không ai nói rằng bạn phải theo dõi nó một cách mù quáng) và các giá trị mặc định được đặt cho các tùy chọn
- mỗi thông số tùy chọn được cung cấp cho một setter
Nói chung, nó được kết hợp với Chaining bao gồm việc đặt các bộ định tuyến trả về tham chiếu đến đối tượng hiện tại để các cuộc gọi có thể được ghép trên một dòng.
class f {
public:
// Take mandatory arguments, set default values
f(int a, int b): _a(a), _b(b), _c(10), _d(20) {}
// Define setters for optional arguments
// Remember the Chaining idiom
f& c(int v) { _c = v; return *this; }
f& d(int v) { _d = v; return *this; }
// Finally define the invocation function
void operator()() const;
private:
int _a;
int _b;
int _c;
int _d;
}; // class f
Các gọi là:
f(/*a=*/1, /*b=*/2).c(3)(); // the last() being to actually invoke the function
Tôi đã nhìn thấy một biến thể đặt các đối số bắt buộc như tham số cho operator()
, điều này tránh việc giữ các đối số như là thuộc tính nhưng cú pháp là kì quặc một chút:
f().c(3)(/*a=*/1, /*b=*/2);
Khi trình biên dịch đã inlined tất cả các hàm tạo và gọi hàm (đây là lý do tại sao chúng được định nghĩa ở đây, trong khi operator()
thì không), nó nên res ult trong mã hiệu quả tương tự so với lời gọi hàm "thường xuyên".
chính xác bạn muốn đạt được điều gì? tôi có cảm giác bất cứ điều gì bạn đang cố gắng làm có thể được thực hiện một cách đơn giản hơn. đoạn mã trên trông giống như khởi đầu của một cơn ác mộng bảo trì. –
@AndersK. Một cách để xác định đối số nào tôi muốn sử dụng. Tôi đồng ý rằng nó không nên được thực hiện, nhưng tôi vẫn còn tò mò nếu có thể. – Pubby
Bạn có thực sự cần nó? Bạn sẽ phải xem xét (N!) Biến thể của các đối số đặt. 4! = 24 định nghĩa. It's * khá * rõ ràng hơn để vượt qua tất cả các thông số –