Лучший способ проверить наличие оператора в C ++ 11
Мне нужно проверить, имеет ли данный класс<<(cls, ostream)
определен оператор или нет. Если так, я хочу, чтобы моя функция использовала это для записи вostringstream
в противном случае следует использовать стандартный код.
Я знаю, что этот вопрос уже задавался. Тем не менее, я обычно нахожу нестандартные решения, которые не всегда работают на моем компиляторе (clang ++). После многих часов поиска я наконец-то обнаружил, что boost :: type_traits. Я не смотрел туда раньше, потому что предполагал, что c ++ 11 уже скопировал все в отделе черт, который имел boost.
Решение, которое работало для меня, было сделать:
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();
}
с участиемto_string
определяется как:
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.";
}
};
Поэтому я публикую это по двум причинам:
Проверьте, является ли этот метод наиболее подходящим для использования, или посмотрите, может ли кто-то другой предложить более лучшее решение (т. Е. Вопрос скорее из любопытства, чем «сработает ли это?» - он уже работает для меня)
Опубликуйте это, чтобы сэкономить кому-то еще часы поиска на тот случай, если ей / ей понадобится что-то подобное.
В качестве более общего вопроса - иногда классы признаков возвращают std :: true_type или std :: false_type (ну, по крайней мере, для классов без наддува). В других случаях они bools. Есть ли причина этого несоответствия? Еслиboost:has_left_shift
возвратил тип вместоbool
тогда у меня мог быть только одинto_string
структура.