У меня есть несколько функций перегрузки, как показано ниже:
template<typename T>
struct Point {
std::enable_if_t<std::is_arithmetic_v<T>, T>
x, y;
};
// These are two functions accepting only Point<> type.
template <typename T>
std::enable_if_t < std::is_class_v<T>
&& std::is_arithmetic_v<decltype(T::x)>
&& std::is_arithmetic_v<decltype(T::y)>
&& sizeof(T) == sizeof(decltype(T::x)) + sizeof(decltype(T::y)), T>
get(const char* key, T defaultValue)
{
// do something ..
return defaultValue;
}
template <typename T>
void set(const char* key, std::enable_if_t < std::is_class_v<T>
&& std::is_arithmetic_v<decltype(T::x)>
&& std::is_arithmetic_v<decltype(T::y)>
&& sizeof(T) == sizeof(decltype(T::x)) + sizeof(decltype(T::y)), T> value)
{
// do something ..
}
template <typename T>
std::enable_if_t <std::is_arithmetic_v<T>, T>
get(const char* key, T defaultValue)
{
return defaultValue;
}
template <typename T>
std::enable_if_t <std::is_enum_v<T>, T>
get(const char* key, T defaultValue)
{
return defaultValue;
}
// There are others overloading get<>(), set<>() for other types.
// Then call them
auto pod1 = get<int>(key, {});// OK
auto pod2 = get<float>(key, {});// OK
auto enm = get<SomeEnum>(key, {});// OK
auto pt1 = get<Point<int>>(key, {}); // OK
auto pt2 = get<Point<std::string>>(key, {}); // failed - correctly.
Пока код работает хорошо, но выглядит довольно многословно.
То, что я хочу здесь, это то, что это самый лучший способ избежать повторения проверки типа Point <> в функциях get / set?.
Я пробовал вот так, но они не работают:
template <typename T>
using is_point_t = std::enable_if_t <
std::is_class_v<T>
&& std::is_arithmetic_v<decltype(T::x)>
&& std::is_arithmetic_v<decltype(T::y)>
&& (sizeof(T) == sizeof(decltype(T::x)) + sizeof(decltype(T::y))), T>;
template <typename T>
is_point_t<T>
get(const char* key, T defaultValue)
{
// do something
return defaultValue;
}
template <typename T>
void set(const char* key, is_point_t<T> value)
{
// do something
}
// Or even like this, it also fails
template <typename T>
inline constexpr bool is_point_v = std::is_class_v<T>
&& std::is_arithmetic_v<decltype(T::x)>
&& std::is_arithmetic_v<decltype(T::y)>
&& (sizeof(T) == sizeof(decltype(T::x)) + sizeof(decltype(T::y)));
template <typename T>
std::enable_if_t <is_point_v<T>, T>
get(const char* key, T defaultValue)
{
// do something
return defaultValue;
}
template <typename T>
void set(const char* key,
std::enable_if_t <is_point_v<T>, T> value)
{
// do something
}
В MSVC 2019 ошибка C1001: в компиляторе произошла внутренняя ошибка. ошибка C1001: Чтобы обойти эту проблему, попробуйте упростить или изменить программу рядом с местами, перечисленными выше.