najlepszy sposób na sprawdzenie istnienia operatora w c ++ 11
Muszę sprawdzić, czy dana klasa ma<<(cls, ostream)
operator zdefiniowany lub nie. Jeśli tak, chcę, aby moja funkcja używała tego do pisaniaostringstream
, w przeciwnym razie należy użyć kodu zastępczego.
Wiem, że to pytanie zostało zadane wcześniej. Jednak zazwyczaj znajduję niestandardowe rozwiązania, które nie zawsze działają na moim kompilatorze (clang ++). Po wielu godzinach poszukiwań w końcu odkryłem, że boost :: type_traits. Nie patrzyłem tam wcześniej, ponieważ założyłem, że c ++ 11 już skopiował wszystko w dziale cech, które pobudziło.
Rozwiązaniem, które zadziałało dla mnie, było:
template <typename C>
std::string toString(C &instance) {
std::ostringstream out;
out << to_string<C, boost::has_left_shift<C, std::ostream>::value>::convert(ctx);
return out.str();
}
zto_string
zdefiniowana jako:
template <typename C, bool>
struct to_string {
// will never get called
static std::string convert(LuaContext &ctx) {}
};
template <typename C>
struct to_string<C, true> {
static std::string convert(LuaContext &ctx) {
return "convert(true) called.";
}
};
template <typename C>
struct to_string<C, false> {
static std::string convert(LuaContext &ctx) {
return "convert(false) called.";
}
};
Dlatego publikuję to z dwóch powodów:
Sprawdź, czy jest to najprostsza metoda, lub sprawdź, czy ktoś inny może zasugerować jeszcze lepsze rozwiązanie (tj. Pytanie jest bardziej z ciekawości podejścia niż „czy to zadziała?” - już działa dla mnie)
Prześlij to, aby zaoszczędzić komuś innym godzin wyszukiwania w przypadku, gdy on / ona również musi coś zrobić.
Jako bardziej ogólne pytanie - czasami klasy cech wydają się zwracać std :: true_type lub std :: false_type (cóż, przynajmniej w przypadku klas bez wzmocnienia). Innym razem są boole. Czy istnieje powód tej rozbieżności? Jeśliboost:has_left_shift
zwrócił typ zamiast abool
, wtedy mógłbym mieć tylko jedento_string
struct.