I have several overloading functions like below:
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.
So far the code works well but they look quite verbose.
What I want here is what is the neatest way to avoid repetition of checking Point<> type in get/set functions?.
I have tried like these but they do not work:
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
}
In MSVC 2019 error C1001: An internal error has occurred in the compiler. error C1001: To work around this problem, try simplifying or changing the program near the locations listed above.
Aucun commentaire:
Enregistrer un commentaire