如何编写一个与普通指针类型( T*
)或 <memory>
中定义的特殊指针类型兼容的函数如std::unique_ptr
?
我尝试使用std::is_pointer
检查,但看起来这不是正确的方法:
#include <iostream>
#include <memory>
template<typename T>
void SomePointerFunction(
T p, typename std::enable_if<std::is_pointer<T>::value>::type* = nullptr) {
std::cout << (p ? "not null" : "null") << std::endl;
}
int main() {
int* p;
std::unique_ptr<int> q;
SomePointerFunction(p); // If we cange p to q, template matching fails
return 0;
}
是否有某种在 C++ 中定义的通用指针类型可以封装这些不同类型的指针,或者可以实现此目的的不同模板检查?
经过更多思考,我也明白为什么这实际上是该语言的一个不受欢迎的特性,因为这两种类型的指针在很多方面都非常不同。但是,如果您只想编写一个利用指针取消引用属性的函数,那么这似乎很有用。有没有办法说“这个函数需要一个参数,为此定义了运算符*
”?
最佳答案
Is there some way to say "This function takes one argument, for which the operator * is defined"?
有,只需尝试取消引用它。如果不起作用,SFINAE 就会启动:
template<typename T, typename = decltype(*std::declval<T>())>
我们使用 std::declval
来获取 T
,取消引用它并尝试获取 decltype。最终结果被忽略,我们只需要它来编译,这意味着 T
是可取消引用的。
#include <iostream>
#include <memory>
template<typename T, typename = decltype(*std::declval<T>())>
void SomePointerFunction(
T& p) {
std::cout << (p ? "not null" : "null") << std::endl;
}
int main() {
int* p = nullptr;
std::unique_ptr<int> q;
int i = 0;
SomePointerFunction(p);
SomePointerFunction(q);
//SomePointerFunction(i);
/* Above prints:
main.cpp: In function 'int main()':
main.cpp:16:24: error: no matching function for call to 'SomePointerFunction(int&)'
*/
return 0;
}
关于C++ 通用指针函数或模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52229613/