Member detection using void_t

…衆ロ難τιáo~ 提交于 2019-12-04 05:08:04

Looking for T::substr is not the same as looking for a member function called substr. gcc.godbolt.org example

You can check if a member function exists by using std::declval<T>() and using decltype to get the return type of the member function.

If the member function exists, decltype(...) will be a well-formed expression and will not trigger SFINAE - therefore the the static_assert will work correctly.

#include <string>
#include <type_traits>
#include <utility>

template <typename...>
using void_t = void;

template <typename, typename = void> 
class HasMember_substr : public std::false_type {};

template <typename T> 
class HasMember_substr<T, void_t<
     decltype(std::declval<T>().substr(1, 1))>
> : public std::true_type {};

static_assert(HasMember_substr<std::string>::value, "");

int main() { return 0; }

Note that decltype(std::declval<T>().substr(1, 1)) checks whether T has a substr member that can be called with arguments 1, 1. (This is not guaranteed to be a member function, it could also be a functor data member, for example.)


As said by AndyG in the comments, another possible approach is using decltype to "validate" the type of a member function pointer.

Example:

HasMember_substr<T, void_t< decltype(&T::substr)>

Note that this will not work if the name substr is overloaded, and it is not guaranteed to work with any type in the standard library.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!