У меня есть шаблон функции, который принимает много разных типов в качестве входных данных. Из этих типов только один из них имеет getInt()
функцию. Поэтому я хочу, чтобы код запускал функцию только для этого типа. Пожалуйста, предложите решение. Спасибо
#include <type_traits>
#include <typeinfo>
class X {
public:
int getInt(){
return 9;
}
};
class Y{
};
template<typename T>
void f(T& v){
// error: 'class Y' has no member named 'getInt'
// also tried std::is_same<T, X>::value
if(typeid(T).name() == typeid(X).name()){
int i = v.getInt();// I want this to be called for X only
}
}
int main(){
Y y;
f(y);
}
type_info
структуре есть оператор сравнения на равенство , поэтому он такжеtypeid(T) == typeid(X)
должен работать.if constexpr
с условиемis_same_v<T,X>
.getInt
член. Здесь, на одном только stackoverflow.com, должно быть довольно много вопросов о том, как посмотреть, есть ли у структуры или класса определенная функция-член, если вы просто выполните небольшой поиск.Ответы:
Если вы хотите иметь возможность вызывать функцию
f
для всех типов, которые имеют член функцииgetInt
, а не толькоX
, вы можете объявить 2 перегрузки для функцииf
:для типов, которые имеют
getInt
функцию-член, включая классX
для всех других типов, включая класс
Y
.C ++ 11 / C ++ 17 решение
Имея это в виду, вы можете сделать что-то вроде этого:
Проверьте это в прямом эфире .
Обратите внимание, что
std::void_t
это введено в C ++ 17, но если вы ограничены C ++ 11, то это действительно легко реализоватьvoid_t
самостоятельно:А вот и версия C ++ 11 в прямом эфире .
Что мы имеем в C ++ 20?
C ++ 20 приносит много хороших вещей, и одна из них - это концепции . Выше всего, что справедливо для C ++ 11 / C ++ 14 / C ++ 17, можно значительно сократить в C ++ 20:
Проверьте это в прямом эфире .
источник
void_t
вызывала проблемы у какого-то старого компилятора (как указано в ссылке).template<typename T> concept HasGetInt = requires (T& v) { {v.getInt()} -> std::convertible_to<int>; };
Вы можете использовать
if constexpr
из C ++ 17:Раньше вам придется использовать перегрузки и SFINAE или диспетчеризацию тегов.
источник
if constexpr
это функция C ++ 17X
Сохраняйте это простым и перегружайте. Работал с C ++ 98 ...
Этого достаточно, если существует только один тип с
getInt
функцией. Если есть больше, это уже не так просто. Есть несколько способов сделать это, вот один:Живой пример с диагностическим выходом.
источник
X
), но, еслиgetInt
в будущем будет больше подобных типов с member , это не очень хорошая практика. Вы, вероятно, хотите отметить, что