我有一个功能void Foo(MyType* mt)。我希望调用者能够将任何指针类型传递给该函数(例如unique_ptr、shared_ptr或iterator),而不需要传递原始指针。有什么办法可以表达这一点吗?我可以写:
template <typename T>
void Foo(T t);
Run Code Online (Sandbox Code Playgroud)
这将起作用,因为它仅在T支持operator->并且operator*我在内部使用时才进行编译Foo,它也仅在T具有相同的接口时才起作用MyType,但未在 API 中指定我希望模板参数是指向的指针似乎是错误的MyType。我还可以编写自己的包装器:
template <typename T>
class PointerWrapper {
public:
PointerWrapper(T* t) : raw_ptr(t) {}
PointerWrapper(const std::unique_ptr<T>& t) : raw_ptr(t.get()) {}
...
private:
T* raw_ptr;
};
void Foo(PointerWrapper<MyType> mt);
Run Code Online (Sandbox Code Playgroud)
这看起来很笨重,因为我需要为每个智能指针类型扩展 PointerWrapper。
有公认的方式来支持这一点吗?
在 C++20 中,您可以编写一个概念,例如
template <typename P, typename T>
concept points_to = requires(P p) {
{ *p } -> std::common_reference_with<T &>
} && std::equality_comparable_with<std::nullptr_t>
template <points_to<MyType> T>
void Foo(T t);
Run Code Online (Sandbox Code Playgroud)
在此之前,你可以写一些涉及std::pointer_traits
template <typename T>
std::enable_if_t<std::is_same_v<MyType, typename std::pointer_traits<T>::element_type>> Foo(T t);
Run Code Online (Sandbox Code Playgroud)