Tôi đã gặp một trường hợp gần đây, nơi tôi có chức năng thành viên const thực hiện một thao tác và trả về kết quả. Ví dụ,Có cách nào tốt để đảm bảo kết quả hàm C++ không bị bỏ qua?
class Foo { ...
Foo add(Foo const & x) const;
}
Nhưng ai đó đã vô tình gọi nó như nó đã được cập nhật các đối tượng this
(bỏ qua kết quả):
Foo a = ...;
Foo b = ...;
a.add(b);
(. Lỗi này đã thực sự được giới thiệu bởi một refactoring không hoàn hảo)
Có cách nào để làm cho dòng cuối cùng ở trên kích hoạt lỗi hoặc cảnh báo không? Điều tốt nhất tiếp theo sẽ là thời gian chạy, chủ yếu được giải quyết bằng mẫu sau. Tuy nhiên, nó sẽ tiêu diệt tối ưu hóa giá trị trả về, như được xem bởi kết quả truy cập.
template<typename T>
class MustTake {
T & obj;
bool took;
public:
MustTake(T o) : obj(o), took(false) {}
~MustTake() { if (!took) throw "not taken"; }
operator T&() { took = true; return obj;}
};
struct Counter {
int n;
Counter() : n(0) {}
Counter(Counter const & c) : n(c.n+1) {}
~Counter() {}
};
Counter zero1() {
return Counter();
}
MustTake<Counter> zero2() {
return Counter();
}
int main() {
Counter c1 = zero1();
printf("%d\n",c1.n); // prints 0
Counter c2 = zero2();
printf("%d\n",c2.n); // prints 1
zero1(); // result ignored
zero2(); // throws
return 0;
}
Tôi cho rằng tôi có thể cải thiện sự kém hiệu quả bằng cách sử dụng một macro để MustTake <> chỉ gỡ lỗi và một không-op cho phát hành.
Tôi đang tìm giải pháp biên dịch. Nếu không, tôi đang tìm giải pháp thời gian chạy tốt nhất.
Trình biên dịch nào bạn đang sử dụng? –
Nếu bạn đang sử dụng GCC, tôi nghĩ rằng nó có cờ '-Wunused-result' để bật cảnh báo cho điều đó. – Xeo
Chọn một tên phương pháp tốt hơn sẽ là gợi ý của tôi. Nếu tôi đọc 'a.add (b) 'tôi sẽ nghĩ ngay lập tức. Làm thế nào về 'a.newListWithHead (b)' hoặc một cái gì đó tương tự, tùy thuộc vào những gì đang thực sự xảy ra? Không gọn gàng như 'add', nhưng việc thêm vào không thực sự là những gì bạn đang làm ở đây. – msandiford