Проверить, могут ли (примитивные) типы приводиться в C ++

Можно ли проверить (в C ++), являются ли типы приводимыми (неявно или явно)? Есть ли что-то в std или можно ли написать функцию, как в C # (C # тот же вопрос)?

Я хочу выполнить эту проверку для типов, а не для экземпляров типа.

Я не уверен насчет системы типов в C ++. Есть ли что-то вроде класса Type в C # или Java? typeid(int) был ближайшим, что я нашел. Могу ли я сохранить тип в переменной? Будем признательны за более внимательные советы по чтению.

Например:

bool isCastable(false);
bool withoutLoss(true);
isCastable = isCastableFromTo(typeid(int), typeid(__int64), withoutLoss); //true
isCastable = isCastableFromTo(typeid(int), typeid(short), withoutLoss); //false
isCastable = isCastableFromTo(typeid(int), typeid(double), withoutLoss); //true
isCastable = isCastableFromTo(typeid(double), typeid(int), withoutLoss); //false
isCastable = isCastableFromTo(typeid(string), typeid(int), withoutLoss); //false

withoutLoss = false;
isCastable = isCastableFromTo(typeid(int), typeid(__int64), withoutLoss); //true
isCastable = isCastableFromTo(typeid(int), typeid(short), withoutLoss); //true
isCastable = isCastableFromTo(typeid(int), typeid(double), withoutLoss); //true
isCastable = isCastableFromTo(typeid(double), typeid(int), withoutLoss); //true
isCastable = isCastableFromTo(typeid(string), typeid(int), withoutLoss); //false

person GiCo    schedule 20.05.2014    source источник
comment
static_cast или для указателей dynamic_cast может вам помочь, но все зависит от вашего варианта использования   -  person Come Raczy    schedule 20.05.2014
comment
В C ++ посмотрите заголовок ‹type_traits› (cplusplus.com/reference/type_traits). Вероятно, вы найдете полезной черту типа std :: is_convertible.   -  person sdkljhdf hda    schedule 20.05.2014
comment
также есть en.cppreference.com/w/cpp/types/bad_cast   -  person user2485710    schedule 20.05.2014
comment
‹Type_traits› - хороший совет, но мы не будем полагаться на C ++ 11.   -  person GiCo    schedule 20.05.2014
comment
bad_cast выбрасывается, только если я пытаюсь применить. Но я хочу проверить, возможно ли приведение на основе типов, а не экземпляров.   -  person GiCo    schedule 20.05.2014
comment
Это пахнет неправильным использованием системы типов C ++. Как правило, кастинг - это запах кода.   -  person Rob K    schedule 20.05.2014
comment
Да пахнет. но для некоторых задач он лучше пахнет, чем навсегда.   -  person GiCo    schedule 20.05.2014
comment
Я пытаюсь написать небольшой общий преобразователь между динамической и статической системой типов. Matlab и c ++. Я пока не знаю, как его оформить без литья.   -  person GiCo    schedule 20.05.2014
comment
<type_traits> - это путь. Если вы не хотите использовать C ++ 11 (почему?!?!), Повторно реализуйте этот заголовок, посмотрев на стандартные реализации библиотеки. Это потребует немало бездумного копирования и вставки, поэтому вам следует действительно использовать версию C ++ 11.   -  person Konrad Rudolph    schedule 21.05.2014
comment
@RobK, я не согласен с тем, что вообще кастинг - это запах кода. Неправильно ли его используют, как и многие другие аспекты C ++? Абсолютно. Но называть это вообще неприятным запахом - явная ложь! :)   -  person Moo-Juice    schedule 21.05.2014
comment
Спасибо! Хорошо, я посмотрю на ‹type_traits› поближе. Я не хочу использовать C ++ 11, потому что файлы mexfiles являются дополнением к (алгоритмическому) фреймворку, который должен иметь открытый исходный код. Я не хочу подталкивать всех пользователей к C ++ 11.   -  person GiCo    schedule 21.05.2014
comment
@GiCo: В C ++ 11 нет ничего плохого. Ваш код не взорвется, а наиболее общие функции поддерживаются достаточно хорошо для всех основных компиляторов.   -  person Danvil    schedule 21.05.2014
comment
@GiCo, вы могли бы стать частью движения за подтолкнуть пользователей к C ++ 11 :)   -  person Moo-Juice    schedule 21.05.2014
comment
Можно ли использовать C ++ 11 в существующем проекте VS 2005? Это для потенциальных пользователей библиотеки комментируемая ситуация.   -  person GiCo    schedule 21.05.2014
comment
@ Moo-Juice: Пользователи из области машиностроения. Некоторые были бы счастливы, если бы у них не было особых проблем с использованием этой библиотеки. ;-)   -  person GiCo    schedule 21.05.2014


Ответы (2)


В C ++ 11 вы можете использовать std::is_convertible (ссылка). Это проверяет, возможно ли неявное преобразование. Не учитывается, будет ли преобразование с потерями.


Пример:

#include <type_traits>
bool f_to_i = std::is_convertible<float,int>::value; // true
bool i64_to_i = std::is_convertible<int64_t,int>::value; // true
bool str_to_i = std::is_convertible<std::string,int>::value; // false
person Danvil    schedule 21.05.2014

Сюда:

template <class F, class T, class = T>
struct is_static_castable : std::false_type
{};

template <class F, class T>
struct is_static_castable<F, T, decltype(static_cast<T>(std::declval<F>()))> : std::true_type
{};
person Pavel Celba    schedule 04.04.2017
comment
OP явно ограничился C ++ 03, см. Комментарии под вопросом. Конечно, тег отсутствовал (я его просто добавил). - person Quentin; 04.04.2017
comment
Обратите внимание, что это не будет работать во всех случаях (например, от float до const int будет ложным). См. Wandbox. - person Matthias; 02.05.2018
comment
Это замечательно, чтобы проверить, может ли указатель F* быть назначен указателю T*. - person Jonathan H; 09.07.2018