c++ - SFINAE 无法正确判断方法是否存在

我正在尝试复制(我猜)典型的 SFINAE 示例来判断一个类型是否具有特定方法。我的代码基本上是 the one found in the accepted answer of a previous popular question on the topic :

#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_backT 的一种方法.我预计我的输出有 3 false行,后跟 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;

https://stackoverflow.com/questions/66509543/

相关文章:

unity3d - 有没有办法在着色器中合并 Unity 中的纹理?

amazon-web-services - AWS Elastic Beanstalk EFS 安装

firebase - 从 Firebase 文档获取时间戳/创建日期,而不是手动保存?

r - 按组保留所有变量的最后一个非缺失观察

java - 如何找到其中包含空元素的整数数组的最大元素的索引?

java - FutureTask get vs run,任务永远不会完成

html - 如何在 svg 圆圈中居中 svg 路径?

javascript - 创建给定字符串的指定副本的字符串

python - 如何链接在两个列表之间创建连接?

javascript - 如何在 NEXT JS 中的路由之间传递状态?