В общем, tuple
следует использовать в родовом коде.
Если вы знаете, что поле 1 является номером или цыпленком, вы не должны использовать tuple
. Вы должны использовать struct
с полем Number
.
Если вам нужен кортеж, как функциональность (как один делает), вы можете просто написать as_tie
:
struct SomeType {
int Number;
std::string Chicken;
auto as_tie() { return std::tie(Number, Chicken); }
auto as_tie() const { return std::tie(Number, Chicken); }
};
Теперь вы можете получить доступ к SomeType
как tuple
ссылок, набрав someInstance.as_tie()
.
Это все еще не дает вам <
или ==
и т. Д. Бесплатно. Мы можем сделать это в одном месте и использовать его везде, где вы использовать as_tie
технику:
struct as_tie_ordering {
template<class T>
using enable = std::enable_if_t< std::is_base_of<as_tie_ordering, std::decay_t<T>>, int>;
template<class T, enable<T> =0>
friend bool operator==(T const& lhs, T const& rhs) {
return lhs.as_tie() == rhs.as_tie();
}
template<class T, enable<T> =0>
friend bool operator!=(T const& lhs, T const& rhs) {
return lhs.as_tie() != rhs.as_tie();
}
template<class T, enable<T> =0>
friend bool operator<(T const& lhs, T const& rhs) {
return lhs.as_tie() < rhs.as_tie();
}
template<class T, enable<T> =0>
friend bool operator<=(T const& lhs, T const& rhs) {
return lhs.as_tie() <= rhs.as_tie();
}
template<class T, enable<T> =0>
friend bool operator>=(T const& lhs, T const& rhs) {
return lhs.as_tie() >= rhs.as_tie();
}
template<class T, enable<T> =0>
friend bool operator>(T const& lhs, T const& rhs) {
return lhs.as_tie() > rhs.as_tie();
}
};
, который дает нам:
struct SomeType:as_tie_ordering {
int Number;
std::string Chicken;
auto as_tie() { return std::tie(Number, Chicken); }
auto as_tie() const { return std::tie(Number, Chicken); }
};
и теперь
SomeTime a,b;
bool same = (a==b);
работ. Обратите внимание: as_tie_ordering
не использует CRTP и является пустым классом без гражданства; этот метод использует Koenig lookup, чтобы экземпляры находили операторы.
Вы также можете реализовать ADL на основе get
struct as_tie_get {
template<class T>
using enable = std::enable_if_t< std::is_base_of<as_tie_get, std::decay_t<T>>, int>;
template<std::size_t I, class T,
enable<T> =0
>
friend decltype(auto) get(T&& t) {
using std::get;
return get<I>(std::forward<T>(t).as_tie());
}
};
Получение std::tuple_size
работать не так просто, к сожалению.
Оговорки enable<T> =0
, приведенные выше, должны быть заменены на class=enable<T>
в MSVC, так как их компилятор не совместим с C++ 11.
Вы обратите внимание, что я использую tuple
; но я использую его в общем. Я конвертирую свой тип в кортеж, затем использую tuple's <
, чтобы написать <
. Этот код клея имеет отношение к галстуку как общий набор типов. Это то, за чем стоит tuple
.
«так их способ обойти это, используя только _using keyword_?» № – cpplearner
Вы не можете одновременно использовать 'C++ 11',' C++ 14', 'C++ 1z'. – Inline
Есть ли какие-либо предложения, кроме как изменить это? –