一些样板:
namespace details {
template<template<class...>class, class, class...>
struct can_apply:std::false_type{};
template<class...>struct voider{using type=void;};
template<class...Ts>using void_t=typename voider<Ts...>::type;
template<template<class...>class Z, class... Ts>
struct can_apply<Z, void_t<Z<Ts...>>, Ts...>:std::true_type{};
} templateclass Z,类... TS> 使用can_apply =细节:: can_apply; 一个特征,以确定是否应*
:
template<class T>
using unary_star_r = decltype(*std::declval<T>());
template<class T>
using can_unary_star = can_apply<unary_star_r, T>;
dispatch
在编译的时候把他们之间的两个参数和选秀权:
template<bool /*false*/>
struct dispatch_t {
template<class T, class F>
F operator()(T, F f)const{ return std::move(f); }
};
template<>
struct dispatch_t<true> {
template<class T, class F>
T operator()(T t, F)const{ return std::move(t); }
};
#define RETURNS(...) \
noexcept(noexcept(__VA_ARGS__))\
->decltype(__VA_ARGS__)\
{ return __VA_ARGS__; }
template<bool b, class T, class F>
auto
dispatch(T t, F f)
RETURNS(dispatch_t<b>{}(std::move(t), std::move(f)))
我们几乎完成了...
现在我们的工作。我们写这代表解引用类型,什么都不做,也许做任何函数对象:
struct maybe_deref_t;
struct do_deref_t;
struct identity_t {
template<class T>
T operator()(T&& t)const { return std::forward<T>(t); }
};
struct do_deref_t {
template<class T>
auto operator()(T&& t)const
RETURNS(maybe_deref_t{}(*std::forward<T>(t)))
};
这里的工作:
struct maybe_deref_t {
template<class T>
auto operator()(T&& t)const
RETURNS(
dispatch< can_unary_star<T>::value >(
do_deref_t{},
identity_t{}
)(
std::forward<T>(t)
)
)
};
和更好的语法帮助:
template<class T>
auto maybe_deref(T&& t)
RETURNS(maybe_deref_t{}(std::forward<T>(t)))
测试代码:
int main() {
auto bob = new int*(new int(7)); // or 0 or whatever
std::cout << maybe_deref(bob) << "\n";
}
live example。
我最初是用C++ 14风格编写的,然后将它翻译回C++ 11。在C++ 14中它更清洁。
不能你写使用['标准:: is_pointer'(HTTP一个_type traits_基于递归模板:// en.cppreference.com/w/cpp/types/is_pointer)还是这样? – user0042
@ user0042'std :: is_pointer'struct只会检查'T'是否是*指针*,而不是迭代器,智能指针等。 –
您是否在寻找[std :: invoke](http:// en .cppreference.com /瓦特/ CPP /实用程序/功能/调用)? –