如何解决如何通过 SFINAE 测试结构是否包含特定成员
为了定义重载函数以将输入字符串解析为特定数据类型,我喜欢以下内容:
#include <type_traits>
// /std:c++17 enabled
template <class T>
constexpr bool is_point_v = std::is_class_v<T> && !std::is_enum_v<T>
&& std::is_arithmetic_v<decltype(T::x)>
&& std::is_arithmetic_v<decltype(T::y)>
&& (sizeof(T) == sizeof(T::y) + sizeof(T::y));
template <class T>
constexpr bool is_rect_v = std::is_class_v<T> && !std::is_enum_v<T>
&& std::is_arithmetic_v<decltype(T::left)>
&& std::is_arithmetic_v<decltype(T::top)>
&& std::is_arithmetic_v<decltype(T::right)>
&& std::is_arithmetic_v<decltype(T::bottom)>
&& (sizeof(T) == sizeof(T::left) + sizeof(T::top) + sizeof(T::right) + sizeof(T::bottom));
template<typename T>
struct Point {
std::enable_if_t<std::is_arithmetic_v<T>,T>
x {},y {};
Point() noexcept {}
};
template<typename T>
struct Rect {
std::enable_if_t<std::is_arithmetic_v<T>,T>
left {},top {},right {},bottom {};
Rect() noexcept {}
};
class DBParser
{
public:
template <typename T>
typename std::enable_if_t<std::is_arithmetic_v<T> || std::is_same_v<T,std::string> || std::is_same_v<T,std::string_view>,T>
get(const char* key,T defaultValue = {}) {
// ...
return defaultValue;
}
template <typename T>
typename std::enable_if_t<is_point_v<T>,T>
get(const char* key,T defaultValue = {}) {
// ...
return defaultValue;
}
template <typename T>
typename std::enable_if_t<is_rect_v<T>,T defaultValue = {}) {
// ...
return defaultValue;
}
};
int main()
{
DBParser db;
auto point1 = db.get<Point<int>>("point1",{});
auto point2 = db.get<Point<float>>("point2",{});
auto rect1 = db.get<Rect<int>>("rect1",{});
auto rect2 = db.get<Rect<float>>("rect2",{});
auto ret3 = db.get<int>("key3",{});
}
编译上面的代码会产生一些错误。显然,我为函数“get”所做的 SFINAE 不正确且有些笨拙,但我无法弄清楚。
你能给我一些代码修复吗?如果 C++17 无法使代码不那么冗长,我接受 C++20。
更新:
为了使问题更贴切问题,我想更改标题并添加更多信息。 奇怪的一件事是,如果我将 struct 的测试直接放在这样的函数中:
template <class T>
std::enable_if_t < std::is_class_v<T> && !std::is_enum_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 defaultValue) { // Point
return defaultValue;
}
它被编译没有错误。所以我认为 Nicol Bolas 的假设可能不正确。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。