Skip to content

Instantly share code, notes, and snippets.

@erwinv
Last active September 16, 2022 09:49
Show Gist options
  • Save erwinv/1db1abffad9124514e12b67e80457011 to your computer and use it in GitHub Desktop.
Save erwinv/1db1abffad9124514e12b67e80457011 to your computer and use it in GitHub Desktop.
Check if member exists via std::enable_if (SFINAE)
#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