我正在使用 C 14 開發一個工具類,它允許開發人員輕松列印各種物件。
對于std::map物件,我嘗試開發這樣一個功能:
template<typename M, typename = std::enable_if_t<
std::is_same<M, std::map<typename M::key_type, typename M::mapped_type>>::value ||
std::is_same<M, std::unordered_map<typename M::key_type, typename M::mapped_type>>::value>>
std::string map2String(const M& mp) {
std::stringstream res;
for (const auto& element : mp) {
res << element.first << "," << element.second << "|";
}
return res.str();
}
它按預期作業。(順便說一句,C 11也可以,我可以用C 11的方式來代替std::enable_if_t。)
然而,正如你看到的std::stringstream已被使用,這意味著M::key_type和M::mapped_type必須流。
但我不知道如何檢查它們是否是流式傳輸的。我需要這樣的東西:
std::enable_if_t<is_streamable<typename M::key_type>>::value
但是is_streamable標準庫中沒有。如果沒有is_streamable,還有其他方法可以為那些在呼叫我的函式時無法寫入流的型別產生編譯時錯誤嗎?
uj5u.com熱心網友回復:
這是在 C 14 中創建自己的型別特征的簡單方法:
#include <type_traits>
#include <utility>
namespace is_streamable_impl {
template <typename T, typename Enable = void>
struct check : public std::false_type {};
template <typename T>
struct check<T,
std::enable_if_t<std::is_same<
decltype(std::declval<std::ostream&>() << std::declval<T>()),
std::ostream&>::value>>
: public std::true_type {};
}
template <typename T>
struct is_streamable : public std::integral_constant<bool, check<T>::value> {};
此特征將檢查os << val的型別是有效的左值運算式std::ostream,給出左值表達os型別std::ostream和表達val與涉及型別和值類別T。也可以撰寫關于確切要求的其他變體。
is_streamable_impl::check上面的定義實際上可能直接作為特征就足夠了。但它確實允許有人將其誤用為check<bad_type, void>::value == true. 您可以將其稱為不良用法而不必擔心;或者這里的模式確保額外的模板引數被隱藏起來。
對于您的示例用途,我實際上會檢查is_streamable<const typename M::key_type&>. 這可能會產生與直接相同的結果key_type,但對于可能很重要的奇怪情況,它更精確。
uj5u.com熱心網友回復:
您可以檢查它們是否可以用作運算元std::ostreamfor operator<<。
template<typename M, typename = std::enable_if_t<
std::is_same<M, std::map<typename M::key_type, typename M::mapped_type>>::value ||
std::is_same<M, std::unordered_map<typename M::key_type, typename M::mapped_type>>::value>,
typename = decltype(std::declval<std::ostream>() << std::declval<typename M::key_type>()),
typename = decltype(std::declval<std::ostream>() << std::declval<typename M::mapped_type>())>
std::string map2String(const M& mp) {
...
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/358921.html
