Допустим, у меня есть несколько разных классов:
class constructible_from_float {
public:
constructible_from_float(float);
};
class constructible_from_double {
public:
constructible_from_double(double);
};
class constructible_from_long_double {
public:
constructible_from_long_double(long double);
};
И затем я хочу сделать что-то, основываясь на том, из какого типа они могут быть построены (упрощенный пример):
#include <type_traits>
template <typename T>
constexpr size_t foo() {
if constexpr (std::is_constructible<T, float>::value) {
return 1;
} else if constexpr (std::is_constructible<T, double>::value) {
return 2;
} else if constexpr (std::is_constructible<T, long double>::value) {
return 3;
} else
return -1;
}
Но проблема в том, что все они возвращают 1
:
[[maybe_unused]] auto float_result = foo<constructible_from_float>();
[[maybe_unused]] auto double_result = foo<constructible_from_double>();
[[maybe_unused]] auto long_double_result = foo<constructible_from_long_double>();
Я знаю, что причина поведения неявна преобразования между типами. Существует ли способ git (используемый по крайней мере в трех основных компиляторах: msvc
, gcc
и clang
), чтобы заставить компилятор различать guish между этими типами.
Мне не разрешено менять классы (constructible_from_float
, et c.), Но я могу делать все остальное. Все, что предусмотрено стабильными версиями компиляторов, в порядке (включая c++2a
).