6

Tôi có hai chức năng mẫu quá tải sau:thống nhất const T & T && quá tải

template<typename T> 
optional<T> some(const T& x) 
{ 
    return optional<T>(x); 
} 

template<typename T> 
typename std::enable_if<std::is_rvalue_reference<T&&>::value, optional<T> >::type 
some(T&& x) 
{ 
    return optional<T>(std::move(x)); 
} 

nỗ lực đầu tiên của tôi tại thống nhất quá tải qua chuyển tiếp hoàn hảo thất bại:

template<typename T> 
optional<T> some(T&& x) 
{ 
    return optional<T>(std::forward<T>(x)); 
} 

error: forming pointer to reference type 'const std::basic_string<char>&' 

Như đã nỗ lực thứ hai của tôi:

template<typename T> 
optional<typename std::remove_reference<T>::type> some(T&& x) 
{ 
    return optional<typename std::remove_reference<T>::type>(std::forward<T>(x)); 
} 

error: no matching function for call to 
'std::basic_string<char>::basic_string(gpa::optional<const std::basic_string<char> >)' 

Có cách nào hợp lý để thống nhất tình trạng quá tải hoặc tôi chỉ nên sống với chúng?

+1

Bạn nên cung cấp định nghĩa về 'tùy chọn <> 'là gì. –

+0

Về cơ bản nó là một bản sao đồ chơi của 'boost :: optional'. – fredoverflow

+1

... Tuy nhiên, câu hỏi là viết tắt, bạn có thể cung cấp định nghĩa không? Tôi có cảm giác rằng vấn đề là với giao diện 'tùy chọn' (nghĩa là chuyển tiếp hoàn hảo là giải pháp cho' some', bạn có thể cần phải tinh chỉnh nó để khớp 'tùy chọn') –

Trả lời

1

Nói chung, cách tốt nhất để làm điều này là để có những đối tượng theo giá trị và để cho các gọi quyết định liệu để sao chép hoặc di chuyển nó:

template<typename T> 
optional<T> some(T x) 
{ 
    return optional<T>(std::move(x)); 
} 

Nếu người gọi gọi nó với một tạm thời hoặc sử dụng std::move trên giá trị của chúng, sau đó nó được di chuyển. Nếu không nó được sao chép.

Có, điều này có nghĩa là bạn sẽ thực hiện thêm một bước nữa (trong đó, nếu chuyển động giống như sao chép, nghĩa là thực hiện hai bản sao). Nếu đó là một vấn đề hiệu suất đáng kể cho bạn, thì bạn sẽ phải sử dụng hai quá trình thực hiện quá tải.

4

Tôi không quen thuộc với optional của bạn, nhưng có lẽ bạn cần phải thêm:

typename remove_const<...>::type 

xung quanh remove_reference ở hai nơi của bạn. (bởi vì quá tải 1 của bạn về giải pháp 2-quá tải của bạn - mà tôi giả định là vượt qua tất cả các bài kiểm tra của bạn - có hiệu quả remove_const khi khai báo optional<T>).

+0

Không phải là' remove_cv' chỉ hãy ở nơi an toàn? – pmr

+1

Nếu đó là những gì mong muốn. Giải pháp 2-quá tải hiện tại chỉ từ chối các giá trị đủ điều kiện dễ bay hơi. Thật khó cho tôi để nói những gì mong muốn mà không có một ví dụ mã hoàn chỉnh. –

Các vấn đề liên quan