Reputation: 901
I am trying to declare a function that checks wether a smart pointer is initialized. I wrote two variants of a function that acts on smart pointers, one template function acting on templates, one acting on a template of a template. The problem is, the latter one is supposed to act on at least std::unique_ptr and std::shared_ptr. The std::unique_ptr one is constructed differently from std::shared_ptr. std::unique_ptr one takes two template arguments (namely object type and deleter) whereas std::shared_ptr one takes only one (namely the object type).
#include <iostream>
#include <memory>
template <typename Smartpointer>
void checkPointerinitialization(const Smartpointer& ptr){
if(!ptr.get())
std::cout<<"smart pointer is not initialized\n"<<std::endl;
}
//template <template <typename, typename> class Smartpointer, typename Object, typename Deleter>
//void checkPointerinitializationWithTemplates(const Smartpointer<Object, Deleter>& ptr){
// if(!ptr.get())
// std::cout<<"smart pointer is not initialized in template function either\n"<<std::endl;
//}
//int main(){
// std::shared_ptr<int> myptr;
// checkPointerinitialization(myptr);
// checkPointerinitializationWithTemplates(myptr);
//
//}
template <template <typename> class Smartpointer, typename Object>
void checkPointerinitializationWithTemplates(const Smartpointer<Object>& ptr){
if(!ptr.get())
std::cout<<"smart pointer is not initialized in template function either\n"<<std::endl;
}
int main(){
std::shared_ptr<int> myptr;
checkPointerinitialization(myptr);
checkPointerinitializationWithTemplates(myptr);
}
My solution was to overload the template function, however if I uncomment the first function, I get a template deduction failed - wrong number of template arguments error message from g++. Is it actually possible to overload the template functions in an appropriate manner?
Upvotes: 0
Views: 359
Reputation: 303537
Instead of taking your argument as an instantiation of a class template with one single template parameter, take your argument as a class template taking at least one template parameter:
template <template <class, class...> class Z,
class Object,
class... Ts>
void foo(const Z<Object, Ts...>& ptr) { ... }
This will match both std::unique_ptr<X>
(with Object=X
and Ts={std::default_delete<X>}
) and std::shared_ptr<X>
(with Object=X
and Ts={}
).
However, this will not match any non-template smart pointers, like:
struct MySpecialSnowflakeSmartPointer { ... };
So your first approach is probably best:
template <class SP>
void foo(SP const& ptr) { ... }
Upvotes: 4