Giả sử tôi muốn sử dụng std::conditional
để xác định loại, nếu loại là vector<...>
thì lợi nhuận sẽ là vector<...>::size_type
và nếu không thì sẽ là int
. (chỉ là một ví dụ).Có thể xây dựng một metafunction lazy_conditional
Một cách ngây thơ để sử dụng std::conditional
:
template<class V> struct is_vector : std::false_type{};
template<class T> struct is_vector<std::vector<T>> : std::true_type{};
template<class C>
using my_size_type = typename std::conditional<
not is_vector<C>::value,
int,
C::size_type // note that this line only makes sense when condition is false
>::type;
Tuy nhiên điều này không thành công vì nếu C
là nói một double
, double::size_type
sẽ đưa ra một lỗi, ngay cả khi đó là việc đánh giá các lựa chọn sai giây.
Vì vậy, tôi tự hỏi nếu có một loại lazy_conditional
trong đó câu lệnh giả (hoặc sai thứ hai) không được đánh giá.
Tôi tìm thấy nội dung nào đó ở đây: https://stackoverflow.com/a/5317659/225186 nhưng tôi không biết cách sử dụng ví dụ của mình.
Lưu ý rằng tôi biết làm thế nào để có được những kết quả tương tự mà không sử dụng std::conditional
:
template<class V> struct my_size_type{typedef int type;};
template<class T> struct my_size_type<std::vector<T>>{typedef std::vector<T>::size_type type;};
Câu hỏi đặt ra là nếu có một lazy_conditional
rằng bằng cách nào đó gói gọn một std::conditional
đó là ngắn mạch.
Sau một số lỗi dùng thử, tôi quản lý để sử dụng ý tưởng trong https://stackoverflow.com/a/5317659/225186 và thực hiện điều này theo sau. Nó cũng làm cho tôi nghĩ rằng không thể viết std::lazy_conditional
bởi vì C::size_type
không thể xuất hiện ở tất cả trong bất kỳ biểu thức nào là ưu tiên, do đó, cần có hai biểu thức bước.
template<class C, bool B> struct false_case{
typedef void type;
};
template<class C> struct false_case<C, false>{
typedef typename C::size_type type;
};
template<class C>
using size_type = typename std::conditional<
not is_vector<C>::value,
int,
typename false_case<C, not is_vector<C>::value>::type
>::type;
Tôi thậm chí không thể ngưng tụ điều này thành macro, vì mỗi trường hợp khác nhau.
Ok, và tôi đoán nó không thể được gói gọn như một 'lazy_conditional'. Dù sao điều này cũng cho thấy rằng metafunction miễn phí tốt hơn thành viên (có std :: size_type_of :: type thay vì dựa vào T :: size_type) khi có thể (như chức năng miễn phí tốt hơn so với hàm thành viên cho mã chung). –
alfC
ah, đây là điều mà tôi khám phá nhiều lần, cuối cùng cũng giống như tôi đã làm ở đây: http://stackoverflow.com/questions/5839357/detect-operator-support-with-decltype-sfinae/18603716# 18603716 – alfC
Trên khả năng tương thích 'detect_or_t': http://stackoverflow.com/questions/36418570/what-compiler-option-library-do-i-need-to-use-detect-or-t-type-trait?noredirect= 1 # comment60486585_36418570 – alfC