假设我有类似的东西:
template <class T>
void do_something(T t){
pass_it_somewhere(t);
t->do_something();
}
现在允许T
成为指针类型或非指针类型会很有用。函数do_something(...)
基本上可以处理指针和非指针,t->do_something()
除外。对于指针,我需要->
,对于非指针,我需要.
来访问成员。
有没有办法让T
接受指针和非指针?
答案 0 :(得分:10)
您可以创建一个解除引用机制,如下所示:
kGGLInstanceIDAPNSServerTypeSandboxOption:@YES
并在您的函数中使用它:
template<typename T>
std::enable_if_t<std::is_pointer<T>::value, std::remove_pointer_t<T>&> dereference(T& t) {
return *t;
}
template<typename T>
std::enable_if_t<!std::is_pointer<T>::value, T&> dereference(T& t) {
return t;
}
这样您只需要使用template <class T>
void do_something(T t){
pass_it_somewhere(dereference(t));
dereference(t).do_something();
}
的具体版本。
答案 1 :(得分:7)
Soultion 1
使用模板专业化:
template <class T>
void do_something(T t){
pass_it_somewhere(t);
t.do_something();
}
template <class T>
void do_something(T* t){
pass_it_somewhere(t);
t->do_something();
}
解决方案2
在T类中添加用户定义的指针运算符:
class A
{
public:
void do_something() const {}
const A* operator->() const { return this; }
};
template <class T>
void do_something(T t){
pass_it_somewhere(t);
t->do_something();
}
答案 2 :(得分:2)
另一种解决方案:标签调度。
namespace detail {
struct tag_value {};
struct tag_ptr {};
template <bool T> struct dispatch { using type = tag_value; };
template <> struct dispatch<true> { using type = tag_ptr; };
template <class T>
void do_call(T v, tag_value)
{
v.call();
}
template <class T>
void do_call(T ptr, tag_ptr)
{
ptr->call();
}
}
然后你的功能变为:
template <class T>
void do_something(T unknown)
{
do_call(unknown,
typename detail::dispatch<std::is_pointer<T>::value>::type{} );
// found by ADL
}