template class specialization
Nov 28, 2017 at 6:27am UTC
I would like to have a template class that can automatically detect whether its template is of the form std::shared_ptr<T>. In particular, I would like to implement the class as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
template <typename T>
class MyTemplateClass {
public :
MyTemplateClass(const T& t) { obj = t; }
void doWork() { obj.doSomething(); }
private :
T obj;
}
template <typename T>
class MyTemplateClass<std::shared_ptr<T> > {
public :
MyTemplateClass(const std::shared_ptr<T>& t) { obj_ptr = t; }
void doWork() { obj->doSomething(); }
private :
std::shared_ptr<T> obj_ptr;
}
int main() {
TestObj obj1;
std::shared_ptr<TestObj> obj2;
MyTemplateClass<TetsObj> t1(obj1);
MyTemplateClass<TetsObj> t2(obj2);
}
The second line fail as the template argument is not of the form "std::shared_ptr<TestObj>". However this is exactly the form I am looking for. How would I get around this?
Nov 28, 2017 at 6:51am UTC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
#include <iostream>
#include <memory>
template < typename T > struct my_class {
explicit my_class( const T& t ) : obj(t) {}
void doWork() { obj.doSomething(); }
private : T obj;
};
template < typename T > struct my_class< std::shared_ptr<T> > {
explicit my_class( const std::shared_ptr<T>& t ) : obj_ptr(t) {}
void doWork() { if (obj_ptr) obj_ptr->doSomething(); }
private : std::shared_ptr<T> obj_ptr;
};
template < typename T > // syntactic sugar
my_class<T> make_my_class( const T& v ) { return my_class<T>(v) ; }
int main() {
struct test
{
void doSomething() const { std::cout << "TestObj::doSomething()\n" ; }
} test_obj ;
auto sptr = std::make_shared<test>() ;
//////////// specify the correct type ///////////////////
my_class<test> t1(test_obj);
t1.doWork() ;
my_class< decltype (sptr) > t2(sptr);
t2.doWork() ;
//////////////////////////////////////////////////////////
///////////////// use syntactic sugar to deduce the correct type //////////
auto t3 = make_my_class(test_obj) ;
t3.doWork() ;
auto t4 = make_my_class(sptr) ;
t4.doWork() ;
//////////////////////////////////////////////////////////
////////// let the compiler deduce the type (only in C++17) //////////////
my_class t5(test_obj) ;
t5.doWork() ;
my_class t6(sptr) ;
t6.doWork() ;
//////////// C++17 /////////////////
}
http://coliru.stacked-crooked.com/a/75ac34486efa1a7b
Nov 28, 2017 at 2:34pm UTC
my 2c using type_traits:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
#include <iostream>
#include <memory>
#include <type_traits>
template <typename T> struct is_shared_ptr : std::false_type {};
template <typename T> struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {}; //to detect std::share_ptr types
template <typename T, typename Enable = void > // primary template
struct my_class
{
explicit my_class( const T& t ) : obj(t) {}
void doWork() const { obj.doSomething(); }
private : T obj;
};
template <typename T> // specialization for is_shared_ptr types
struct my_class <T, typename std::enable_if<is_shared_ptr<T>::value>::type>
{
explicit my_class( const T& t ) : obj_ptr(t) {}
void doWork() const { if (obj_ptr) obj_ptr->doSomething(); std::cout << "shared_ptr version \n" ;}
private : T obj_ptr;
};
template < typename T > // syntactic sugar
my_class<T> make_my_class( const T& v ) { return my_class<T>(v) ; }
int main()
{
struct test
{
void doSomething() const { std::cout << "TestObj::doSomething()\n" ; }
} test_obj ;
auto sptr = std::make_shared<test>() ;
my_class<test> t1(test_obj);
t1.doWork() ;
my_class< std::shared_ptr<test> > t2(sptr);
t2.doWork() ;
auto t3 = make_my_class(test_obj) ;
t3.doWork() ;
auto t4 = make_my_class(sptr) ;
t4.doWork() ;
}
the difference b/w this and above proposal is that the body of my_class implementations are similar in either case with the second template parameter distinguishing whether or not a type is std::shared_ptr <>
Topic archived. No new replies allowed.