Tôi đang cố gắng hiểu std::is_convertible
trong C++ 11. Theo cppreference.com, std::is_convertible<T,U>::value
nên đánh giá thành 1 iff "Nếu có thể sử dụng giá trị tưởng tượng của loại T
trong câu lệnh trả về của hàm trả về U
". Từ ngữ nói không có gì về nơi mà chức năng đó có thể được tuyên bố, mặc dù. Điều gì sẽ xảy ra khi người xây dựng bản sao của U
là riêng tư? Bạn nên mong đợi điều gì khi T
là tham chiếu giá trị l?C++ 11 std :: hành vi is_convertible với hàm tạo bản sao riêng
Ví dụ: xem xét mã này:
#include <iostream>
#include <type_traits>
struct Fact_A;
struct A {
friend struct Fact_A;
A() = default;
A(A&&) = delete;
private:
A(const A&) = default;
};
struct Ref_A {
A* _ptr;
Ref_A(A* ptr) : _ptr(ptr) {}
operator A&() { return *_ptr; }
};
struct Fact_A {
static A* make_A(const A& a) { return new A(a); }
static A f(A* a_ptr) { return Ref_A(a_ptr); }
//static A g(A&& a) { return std::move(a); }
};
int main() {
A a1;
A* a2_ptr = Fact_A::make_A(a1);
(void)a2_ptr;
std::cout << std::is_convertible< Ref_A, A >::value << "\n" // => 0
<< std::is_convertible< Ref_A, A& >::value << "\n" // => 1
<< std::is_convertible< A&, A >::value << "\n"; // => 0
}
Tôi đang sử dụng gcc-4.8.2
hoặc clang-3.4
(có sự khác biệt về sản lượng), và tôi biên dịch với:
{g++|clang++} -std=c++11 -Wall -Wextra eg.cpp -o eg
Ở đây, std::is_convertible< Ref_A, A >
báo cáo 0
. Tuy nhiên, bạn có thể thấy rằng Fact_A::f
trả về một đối tượng thuộc loại A
và một giá trị bằng loại Ref_A
được sử dụng trong báo cáo trả về của nó. Vấn đề là các nhà xây dựng bản sao của A
là private
, do đó, chức năng đó không thể được đặt bất cứ nơi nào khác. Hành vi hiện tại có đúng với tiêu chuẩn không?
Câu hỏi thứ hai. Nếu tôi xóa private
, đầu ra sẽ chuyển thành 1 1 1
. 1
có nghĩa là gì? "Rvalue loại A&
" là gì? Đó có phải là một tham chiếu rvalue? Bởi vì bạn có thể nhận thấy tôi đã xóa một cách rõ ràng hàm khởi tạo của A
. Do đó, tôi không thể khai báo Fact_A::g
. Nhưng vẫn còn, std::is_convertible< A&, A >
báo cáo 1
.
Cảm ơn bạn đã tham khảo. Ngoài những gì bạn đã nói, có nhiều văn bản trực tiếp bên dưới phần nháp mà bạn trích dẫn, cụ thể là đề cập đến các vấn đề ngữ cảnh. Tôi sẽ chấp nhận điều này. Tôi đoán những gì còn lại là một câu hỏi kéo dài về việc liệu các tiêu chuẩn đang làm đúng. Những gì tôi không thích là, 'is_convertible' dường như không cần thiết gắn liền với khả năng truy cập constructor của' To', không liên quan gì đến 'From', hoặc quan hệ giữa' From' và 'To'. Tôi có thể tưởng tượng các tình huống mà tôi thực sự muốn biết liệu chuyển đổi có thể được thực hiện trong bối cảnh lựa chọn của tôi không ... –
@MateiDavid 'is_convertible' cố gắng mô phỏng định nghĩa * chuyển đổi ngầm * mà tôi thấy không rõ ràng chút nào. Bản thân định nghĩa đó yêu cầu một nhà xây dựng sao chép/di chuyển có thể truy cập được. Có thể trong ngữ cảnh của bạn, 'is_constructible' có ý nghĩa hơn. – dyp