Есть ли способ использовать SFINAE, чтобы определить, не вызовет ли вызов шаблонной функции из-за предоставленных типов?
У меня есть шаблонный класс, который я использую, чтобы предоставить метод, который будет использовать boost::lexical_cast
бросить его std::string
параметры к типу, указанному в шаблоне, только если возможно лексическое приведение. В настоящее время, чтобы проверить, если это возможно, я просто проверяю, если operator>>
определяется для рассматриваемого типа. Вот надуманный пример, который в основном иллюстрирует то, что я делаю:
template <typename ArgType, class Enable = void>
MyHelperClass
{
void Foo (ArgType arg&, std::string strArg) { } // not castable; do nothing
};
template <typename ArgType>
MyHelperClass<ArgType, boost::enable_if<boost::has_right_shift<std::istream, ArgType> >::type>
{
void Foo (ArgType arg&, std::string strArg) {
arg = boost::lexical_cast<ArgType>(strArg); // cast string arg to ArgType
}
};
До сих пор это прекрасно работает для моего кода: все типы, которые не проходят лексическое приведение, заканчиваются первой версией, а все остальные заканчиваются второй, по крайней мере для типов, в которых мой код использует это. Что меня беспокоит, так это то, что я в основном делаю предположение, что, пока целевым типом является InputStreamable, lexical_cast не будет работать. В документации для lexical_cast изложены некоторые другие требования, которые я, вероятно, должен также проверить, но не создавать сложные enable-if
и использовать mpl::and_
чтобы связать воедино кучу этих условий, мне было интересно: есть ли способ использовать SFINAE, чтобы просто проверить, является ли этот вызов lexical_cast
потерпит неудачу для указанных типов и будет соответствовать специализированному шаблону, только если он не потерпит неудачу?
Я только когда-либо видел примеры для проверки существования функции или оператора, но никогда не проверял, вызовет ли вызов шаблонной функции с данным типом ошибку.
1 ответ
Боюсь, что нет. Поскольку lexical_cast определен для всех T, SFINAE вам не поможет. Тот факт, что тело lexical_cast() не может быть скомпилировано для определенных типов, не приводит к ошибке замещения. Лучшее, что вы можете сделать, это попытаться предсказать условия, которые приведут к выходу организма из строя, как вы уже это делали.