Chương trình sau đây không xây dựng trong VS11 beta, gcc 4.5, hoặc kêu vang 3,1std :: chủ đề với động phi copyable luận,
#include <thread>
#include <memory>
int main() {
std::unique_ptr<int> p;
std::thread th([](std::unique_ptr<int>) {
},std::move(p));
th.join();
}
Điều này là do các loại đối số là không copyable, nhưng thực hiện các nỗ lực để sao chép nó.
Theo như tôi có thể nói, chương trình này được thiết lập tốt và sẽ hoạt động. Các yêu cầu cho std :: thread dường như ngụ ý rằng các đối số có thể di chuyển, không thể sao chép sẽ hoạt động ở đây. Cụ thể là nó nói rằng đối tượng có thể gọi và mỗi đối số phải thỏa mãn các yêu cầu MoveConstructible và rằng INVOKE(DECAY_COPY(std::forward<F>(f)),DECAY_COPY(std::forward<Args>(args))...)
phải là một biểu thức hợp lệ.
Trong trường hợp này tôi nghĩ biểu hiện hoạt động ra vào một cái gì đó như:
template <class T> typename std::decay<T>::type decay_copy(T&& v)
{ return std::forward<T>(v); }
std::unique_ptr<int> p;
auto f = [](std::unique_ptr<int>) {};
decay_copy(f)(decay_copy(std::move(p)));
Và tôi không nghĩ rằng đây là nghĩa vụ liên quan đến một bản sao của p
. gcc ít nhất có thể biên dịch biểu thức này, mặc dù VS11 thì không.
- Tôi có sai về yêu cầu và đối số phải có thể sao chép được không?
- Tiêu chuẩn có để lại bất kỳ sự cố nào về vấn đề này cho việc triển khai sao chép đối số không?
- Hoặc việc triển khai tôi đã thử không tuân thủ?
Dường như bạn đang chuyển đối số chuỗi theo bản sao (theo chữ ký hàm ẩn danh). Không nên loại đối số là 'std :: unique_ptr &&' hoặc 'const std :: unique_ptr &'? –
@ André: Không có thứ gì đi qua bản sao; chuyển đối số bằng _value_ sẽ sao chép hoặc di chuyển tùy thuộc vào việc người gọi có vượt qua một giá trị hay giá trị rvalue hay không. – ildjarn
@ildjarn: xin lỗi, tôi có nghĩa là "theo giá trị", không phải "theo bản sao". Nó trượt tâm trí của tôi rằng đi qua các đối số theo giá trị sẽ chọn các nhà xây dựng di chuyển nếu có sẵn. –