cuốn sách gpt4 ai đã làm

c++ - boost :: Transform so với std :: Transform

In lại Tác giả: Taklimakan Thời gian cập nhật: 2023-11-03 03:36:22 32 4
mua khóa gpt4 Nike

Từ đoạn mã dưới đây tôi nên kết luận,std::biến đổi So sánh tăng :: biến đổi Thích hợp hơn vì cái trước sử dụng ít bộ khởi tạo và hàm hủy hơn và có lẽ hiệu quả hơn cái sau?

#include 
#include
lớp Ftor {
public:
Ftor(const Ftor& rhs): t(rhs.t)
{ std::cout << " Ftor : copy\n" }
Ftor(tỷ giá thả nổi) : t(tỷ giá)
{ std::cout << " Ftor : init\n" }
~Ftor()
{ std::cout << "~Ftor : ...\n" }
toán tử float() (float x) { return x < t ?
private:
phao t;
};

typedef std::vector vec_t;

int chính (void)
{
vec_t arg(/*...*/);
vec_t val(arg.size());
phao x = 1,0;
/*Kiểm tra biến đổi tiêu chuẩn */
std::cout << "Biến đổi tiêu chuẩn:\n";
std::transform(arg.begin(), arg.end(), val.begin(), Ftor(x));
std::cout << "Tăng cường biến đổi:\n";
/*Kiểm tra biến đổi tăng cường */
boost::transform(boost::make_iterator_range(arg.begin(), arg.end()),
val.begin(), Ftor(x));
}

Đầu ra:

Biến đổi tiêu chuẩn:
Dành cho: khởi tạo
~Ftor: ...
Tăng cường chuyển đổi:
Dành cho: khởi tạo
Dành cho: sao chép
~Ftor: ...
~Ftor: ...

Chuyển đổi tiêu chuẩn sử dụng 2 cuộc gọi. Việc chuyển đổi Boost sử dụng 4 cuộc gọi. Chuyển đổi tiêu chuẩn thắng. vẫn……?

phụ lục

Như @sehe đã đề xuất,std::ref mọi cuộc gọibiến đổi lưu một hàm tạo khităng :: biến đổi Chỉ sử dụng một cuộc gọi. Nhưng std::ref Các biến tạm thời không thể được truyền dưới dạng tham số. Tuy nhiên, vượt qua Ftor f(x) Không sao đâu vì sau này có địa chỉ rõ ràng.

Các lệnh gọi hàm tạo/hàm hủy được tính khi biến đổi được gọi trong vòng lặp. Bây giờ tôi có hai tùy chọn tăng cường:

std::cout << "với std::ref\n";
vì (/*...*/) {
x = ...;
f = Ftor(x);
boost::transform(arg, val.begin(), std::ref(f));
}

std::cout << "với tạm thời\n";
vì (/*...*/) {
x = ...;
boost::transform(arg, val.begin(), Ftor(x));
}

Đầu ra:

với std::ref
Dành cho: khởi tạo
Dành cho: khởi tạo
...
~Ftor: ...
với tạm thời
Dành cho: khởi tạo
Dành cho: sao chép
~Ftor: ...
~Ftor: ...
Dành cho: khởi tạo
Dành cho: sao chép
~Ftor: ...
~Ftor: ...
...

Tôi có gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4 để sử dụng hoặc không sử dụng -O3 sẽ tạo ra kết quả tương tự.

Việc các hàm tạo/hàm hủy có "đắt" hay không là liên quan đếntoán tử()Về mặt. Đây là sản phẩm cuối cùng sẽ thực hiện các phép toán ít đòi hỏi khắt khe hơn, không giống như ví dụ trên.

Ví dụ hoàn chỉnh về coliru

câu trả lời hay nhất

Các thuật toán STL có thể sao chép các vị từ/hàm năng của chúng. Điều này chủ yếu là do chúng được truyền theo giá trị.

您看到的是 tăng xong一次 Chuyển tiếp cuộc gọi.

Bạn có câu hỏi?

Thường thì không. Trình biên dịch rất giỏi trong việc nội tuyến, sao chép và phân tích phụ thuộc.

Rất có thể, mã được tạo sẽ giống hệt nhau.

Tất nhiên, việc thêm cout các câu lệnh hoàn toàn phá hỏng điều đó. không có tác dụng phụ của hàm tạo/hàm hủy làm hỏng nó!

so sánh công bằng dùng không có tác dụng phụĐược tạo cho các biến thể STL và Boostnhư nhauMã số:http://paste.ubuntu.com/14544891/

Sửa chữa

Theo cách thiết kế STL (và các thuật toán tăng cường), bạn có thể chuyển các functor một cách rõ ràng bằng cách tham chiếu nếu cần. Bạn sử dụng cho việc này std::ref:

Sống Trên Coliru

#include 
#include
#include
#include
#include

lớp Ftor {
public:
Ftor(const Ftor &rhs) : t(rhs.t) { std::cout << " Ftor : copy" << std::endl }
Ftor(tỷ lệ thả nổi) : t(tỷ lệ) { std::cout << " Ftor : init" << std::endl }
~Ftor() { std::cout << "~Ftor : ..." << std::endl }
toán tử float()(float x) { return x }

private:
phao t;
};

typedef std::vector vec_t;

int chính(void) {
vec_t arg(190, 1), val(arg.size());

{
std::cout << "Biến đổi STL: " << std::endl;
Ftor f(1.0);
std::transform(arg.begin(), arg.end(), val.begin(), std::ref(f));
}
std::cout << "-----\n";

{
std::cout << "Tăng cường biến đổi: " << std::endl;
Ftor f(1.0);
boost::transform(arg, val.begin(), std::ref(f));
}
std::cout << "-----\n";
}

In

Biến đổi STL: 
Dành cho: khởi tạo
~Ftor: ...
-----
Tăng cường chuyển đổi:
Dành cho: khởi tạo
~Ftor: ...
-----

Để ý Dù sao, hãy sử dụng thuật toán phạm vi trên vùng chứa và xây dựng phạm viRất rất mỉa mai boost::make_iterator_range(arg.begin() , arg.end()) thay vì chỉ sử dụng tranh cãi:

boost::transform(arg, val.begin(), Ftor(x));

Về c++ - boost::transform so với std::transform, chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/34837866/

32 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress