如何解决基于 is_pointer 特性的模板特化
我确定之前已经回答过这个问题,但我不确定我的问题的正确术语/措辞是什么。
以下面的示例类为例:
class Fooable {
public:
int foo(int a);
};
我想编写一个模板类,它可以调用任何泛型类型的 foo() 方法,无论它是指针类型还是引用:
template <typename T>
class FooableCaller {
public:
void useFooWithSomeContext(?) {
//This method needs to use the foo() method of some Fooable to
int a = _getA();
int b; //Returned from foo()
//Depends on if the Fooable passed as an argument is a pointer or reference type
//b = fooable.foo(a);
//b = fooable->foo(a);
_doWork(b);
}
private:
int _getA();
void _doWork(int a);
};
int main() {
Fooable f1;
std::shared_ptr<Fooable> f2 = std::make_shared<Fooable>();
//If I want to call foo() of f1,I have to do f1.foo();
//If I want to call foo() of f2,I have to do f2->foo();
//What is the correct want to write FooableCaller so that useFooWithSomeContext is select to use either . or -> depending on if T is reference or a pointer?
FooableCaller<?> fc1;
FooableCaller<?> fc2;
fc1.useFooWithSomeContext(f1);
fc2.useFooWithSomeContext(f2);
}
这是使用 std::is_pointer 特性的好地方吗?如果是,我该如何正确使用它?
我希望这是有道理的。
解决方法
这是使用 std::is_pointer
特性的好地方吗?
不完全是,尽管特征会有所帮助。 std::is_pointer
确定类型是否为 cv 限定的原始指针,而您的示例使用类型 std::shared_ptr
,一种类似指针的容器类型。您可以首先定义自己的特征来检测类型上的适当 operator*
:
template <typename Ptr,typename T>
using is_pointer_like_of = std::is_same<decltype(*std::declval<Ptr>()),T&>;
然后您可以将此特征与 std::enable_if
一起使用来定义以下对 SFINAE 友好的模板方法:
template <typename T>
class FooableCaller {
public:
void callFoo(T& fooable) {
// do a little more work
fooable.foo();
}
template <typename Ptr>
typename std::enable_if<is_pointer_like_of<Ptr,T>::value>::type callFoo(Ptr p) {
callFoo(*p);
}
};
必须使用 typename
说明符来表明 dependent name ::type
是 std::enable_if<...>
的成员 typedef,即 void
,而不是成员值。
最后,您可以像这样使用 FooableCaller
:
int main() {
Fooable f1;
std::shared_ptr<Fooable> f2 = std::make_shared<Fooable>();
FooableCaller<Fooable> fooableCaller;
fooableCaller.callFoo(f1);
fooableCaller.callFoo(f2);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。