Last active
September 16, 2022 09:49
-
-
Save erwinv/1db1abffad9124514e12b67e80457011 to your computer and use it in GitHub Desktop.
Check if member exists via std::enable_if (SFINAE)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string> | |
#include <type_traits> | |
#include <vector> | |
using StringVec = std::vector<std::string>; | |
namespace | |
{ | |
struct Fallback{}; | |
struct TryExistenceCheckOverloadFirst : public Fallback{}; | |
template<typename T> struct MemberDetector : public std::true_type {}; | |
template<typename T, typename U, | |
std::enable_if_t< | |
MemberDetector<decltype(T::refs)>::value and | |
std::is_same<decltype(T::refs), StringVec>::value | |
, int> = 0> | |
void mapMultipleRefs(T obj, std::vector<U>& acc, TryExistenceCheckOverloadFirst) | |
{ | |
std::cout << "detected plural refs (new meta)" << std::endl; | |
} | |
template<typename T, typename U> | |
void mapMultipleRefs(T obj, std::vector<U> acc, Fallback) | |
{ | |
std::cout << "detected NO plural refs (deprecated)" << std::endl; | |
} | |
template<typename T, typename U, | |
std::enable_if_t< | |
MemberDetector<decltype(T::ref)>::value and | |
std::is_same<decltype(T::ref), std::string>::value | |
, int> = 0> | |
void mapSingleRef(T obj, std::vector<U>& acc, TryExistenceCheckOverloadFirst) | |
{ | |
std::cout << "detected singular ref (deprecated)" << std::endl; | |
} | |
template<typename T, typename U> | |
void mapSingleRef(T obj, std::vector<U>& acc, Fallback) | |
{ | |
std::cout << "detected NO singular ref (new meta)" << std::endl; | |
} | |
} | |
struct A0 | |
{ | |
std::string ref; | |
}; | |
struct A1 | |
{ | |
std::string ref; | |
std::vector<std::string> refs; | |
}; | |
struct A2 | |
{ | |
std::vector<std::string> refs; | |
}; | |
struct B | |
{}; | |
int main() | |
{ | |
std::vector<B> acc; | |
::mapSingleRef(A0{}, acc, TryExistenceCheckOverloadFirst{}); | |
::mapMultipleRefs(A0{}, acc, TryExistenceCheckOverloadFirst{}); | |
::mapSingleRef(A1{}, acc, TryExistenceCheckOverloadFirst{}); | |
::mapMultipleRefs(A1{}, acc, TryExistenceCheckOverloadFirst{}); | |
::mapSingleRef(A2{}, acc, TryExistenceCheckOverloadFirst{}); | |
::mapMultipleRefs(A2{}, acc, TryExistenceCheckOverloadFirst{}); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment