我試圖復制(我猜)典型的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
的方法。我希望我的輸出有3行false
,后面是3行true
。但是,這是實際輸出:
false
false
false
false
false
true
我錯過什么了嗎?
(附言:有沒有更標準或更好的方法來編寫這樣一個類?)
此方法僅適用于non-overloaded函數。如果它重載了,就不能對它進行pointer-to-member,除非您立即將它轉換為特定的指針類型。
這種類型轉換是error-prone,因此我建議嘗試調用函數:
在國際海事組織看來,在相關的答復中所建議的SFINAE方法是不必要的冗長。我會這么做: