std::experimental::is_detected
및 유사한 검색 유틸리티의 첫 번째 인수로 어떤 종류의 템플릿을 사용할 수 있는지 알고 싶습니다.is_detected와 함께 어떤 종류의 템플릿을 사용할 수 있습니까?
아래 붙여 넣기는 is_detected
의 구현이며 유형 T
에 .foo()
이라는 멤버 함수가 있는지 검색하는 데 사용하려고했습니다. 이 사용하는 일반적인 패턴이 존재하는 경우 우선, 멤버 함수 T::foo
의 타입을 반환하는 타입 특성을 정의하는 것이다
template<class T>
using member_foo_result_t = typename member_foo_result<T>::type;
문제 : 다음
template<class T>
struct member_foo_result
{
using type = decltype(std::declval<T>().foo());
};
그것은 속기 별명을 정의 약식 별칭이 is_detected
과 호환되지 않는 것 같습니다.
여기 컴파일러 출력, 전체 프로그램의 : 런타임시 :
#include <utility>
#include <type_traits>
#include <iostream>
// implementation of is_detected
template<class...>
using void_t = void;
struct nonesuch
{
nonesuch() = delete;
~nonesuch() = delete;
nonesuch(const nonesuch&) = delete;
void operator=(const nonesuch&) = delete;
};
template<class Default, class AlwaysVoid,
template<class...> class Op, class... Args>
struct detector
{
using value_t = std::false_type;
using type = Default;
};
template<class Default, template<class...> class Op, class... Args>
struct detector<Default, void_t<Op<Args...>>, Op, Args...>
{
using value_t = std::true_type;
using type = Op<Args...>;
};
template<template<class...> class Op, class... Args>
using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
// returns the result type of T::foo()
template<class T>
struct member_foo_result
{
using type = decltype(std::declval<T>().foo());
};
// shorthand alias for member_foo_result<T>::type
template<class T>
using member_foo_result_t = typename member_foo_result<T>::type;
// detects whether or not the member function T::foo() exists
template<class T>
struct has_foo_member : is_detected<member_foo_result_t, T> {};
struct doesnt_have_foo_member {};
int main()
{
std::cout << "result: " << has_foo_member<doesnt_have_foo_member>::value << std::endl;
}
나는이 프로그램이 "0 결과를"인쇄 할 전망이다. 그러나 올바르게 컴파일되지 않습니다.
$ clang -std=c++11 test_is_detected.cpp
test_is_detected.cpp:41:43: error: no member named 'foo' in 'doesnt_have_foo_member'
using type = decltype(std::declval<T>().foo());
~~~~~~~~~~~~~~~~~^
test_is_detected.cpp:45:1: note: in instantiation of template class 'member_foo_result<doesnt_have_foo_member>' requested here
using member_foo_result_t = typename member_foo_result<T>::type;
^
test_is_detected.cpp:27:33: note: in instantiation of template type alias 'member_foo_result_t' requested here
struct detector<Default, void_t<Op<Args...>>, Op, Args...>
^
test_is_detected.cpp:33:1: note: during template argument deduction for class template partial specialization 'detector<type-parameter-0-0, void, Op, type-parameter-0-2...>' [with Default = nonesuch, Op =
member_foo_result_t, Args = <doesnt_have_foo_member>]
using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
^
test_is_detected.cpp:50:25: note: in instantiation of template type alias 'is_detected' requested here
struct has_foo_member : is_detected<member_foo_result_t, T> {};
^
test_is_detected.cpp:58:30: note: in instantiation of template class 'has_foo_member<doesnt_have_foo_member>' requested here
std::cout << "result: " << has_foo_member<doesnt_have_foo_member>::value << std::endl;
^
1 error generated.
내가 잘못 사용하고 있습니까 is_detected
?