c++ - SFINAE 没有正确判断方法是否存在
问题描述
我试图复制(我猜)典型的 SFINAE 示例来判断一个类型是否具有某种方法。我的代码基本上是在先前关于该主题的热门问题的已接受答案中找到的代码:
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <list>
template <typename T>
class has_push_back_sfinae {
typedef int8_t yes;
typedef int16_t no;
template <typename C> static constexpr yes test(decltype(&C::push_back));
template <typename C> static constexpr no test(...);
public:
static constexpr bool value = (sizeof(test<T>(0)) == sizeof(yes));
};
template <typename T>
constexpr bool has_push_back = has_push_back_sfinae<T>::value;
int main() {
std::cout << std::boolalpha;
std::cout << has_push_back<int> << std::endl;
std::cout << has_push_back<std::set<int>> << std::endl;
std::cout << has_push_back<std::map<int, char>> << std::endl;
std::cout << has_push_back<std::vector<char>> << std::endl;
std::cout << has_push_back<std::list<int>> << std::endl;
std::cout << has_push_back<std::string> << std::endl;
return 0;
}
基本上,has_push_back<T>
意味着true
当且仅当push_back
是 的一种方法T
。我希望我的输出有 3false
行,然后是3 行true
。但是,这是实际输出:
false
false
false
false
false
true
我错过了什么吗?
(PS:有没有更标准或更好的方式来编写这样的类?)
解决方案
此方法仅适用于非重载函数。如果它被重载,你不能创建指向它的成员指针,除非你立即将它转换为特定的指针类型。
这种转换容易出错,所以我建议尝试调用该函数:
/*...*/ constexpr yes test(decltype(void(
std::declval<C &>().push_back(std::declval<const typename C::value_type &>())), int{}));
IMO,链接答案中建议的 SFINAE 方法不必要地冗长。这是我要做的:
template <typename T, typename = void> struct has_push_back_sfinae : std::false_type {};
template <typename T> struct has_push_back_sfinae<T,
decltype(void(std::declval<T &>().push_back(std::declval<const typename T::value_type &>())))
> : std::true_type {};
template <typename T> inline constexpr bool has_push_back = has_push_back_sfinae<T>::value;
推荐阅读
- ios - 属性更改后在 SwiftUI 中更新列表
- javascript - 具有固定和的随机整数
- github - 如何将 Dependabot 与私有包一起使用
- excel - 计算逗号分隔列表的第一个值和最后一个值之间的差异
- python - 如何从 django rest 框架中的父模型中具有外键的子模型中过滤字段?
- pandas - Pandas:ValueError 使用 `at` 进行迭代
- python - OpenCV 找不到用于网络摄像头的 VideoCapture 或在 Windows 10 上显示
- list - 从知识库中检索受限列表
- html - 悬停时如何同时更改svg和文本的颜色?
- java - 孩子的Firebase订单不返回任何数据