Unanswered something about total template specialization

  • Friday, September 21, 2012 9:02 AM
     
      Has Code

    shared_ptr approach can be swapped but the following swap said identifier not found

    #include <stdio.h>
    #ifndef    FATHER_DEF
    #define    FATHER_DEF
    class Father{
    public:
    	Father() {}
    	virtual void print()
    	{ 
    		printf("a%d", money);
    	}
    	virtual void setMoney(int h)
    	{ 
    		money = h;
    	}
    	virtual int getMoney()
    	{ 
    		return money;
    	}
    	
    	Father(const Father& rhs);
    	Father& operator=(const Father& rhs)
    	{
    		*pImpl = *(rhs.pImpl);
    	}
    	void swap(Father& other)
    	{
    		using std::swap;
    		swap(pImpl, other.pImpl);
    	}
    private:
    	int money;
    	Father* pImpl;
    };
    #endif
    #include <stdio.h>
    #include "Father.h"
    #ifndef    SON_DEF
    #define    SON_DEF
    class Son : public Father
    {
    public :
    	
    	Son()
    	{
    	}
    	
    	virtual void print()
    	{ 
    		printf("b%d", getMoney());
    	}
    };
    #endif
    #include <stdio.h>
    #include "Father.h"
    #ifndef    SON2_DEF
    #define    SON2_DEF
    class Son2 : public Father
    {
    public :
    	/*
    	Son2()
    	{
    	}
    	*/
    	virtual void print()
    	{ 
    		printf("c%d", getMoney());
    	}
    };
    #endif
    	Father* dummy = new Son();
    	Father* s1 = new Son();
    	Father* s2 = new Son2();
    	dummy->setMoney(3000);
    	s1->setMoney(5000);
    	s2->setMoney(6000);
    	shapes.push_back(dummy);
    	shapes.push_back(s1);
    	shapes.push_back(s2);
    	
    	// identifier not found
    	swap(s1,s2); 
    	s1->print();
    	//error C2664: 'Father::swap' : cannot convert parameter 1 from 'Father *' to 'Father &'
    	s1->swap(s2); 

    namespace std{
    template<>
    void swap<Father>(Father& a, Father& b)
    {
    	a.swap(b);
    }
    }


    飲杯紅棗茶,切記矇查查

All Replies

  • Friday, September 21, 2012 9:32 AM
    Moderator
     
     

    "identifier not found"

    Your swap specialization is still in the std namespace, do you have a "using namespace std;" somewhere before that line? If not use std::swap instead of just swap.

    But anyway, it won't work. s1 and s2 are pointers to Father, that swap specialization expects references.

    "error C2664..."

    Again, you're using pointers and that swap method expects references. Try s1->swap(*s2) instead.

    I'm not sure what you're trying to achieve but there's a difference in how you use Father in this code and how shared_ptr is usually used. You're using pointers to Father but in the case of shared_ptr it's not common to see a pointer to a shared_ptr, after all it acts like a pointer itself.

  • Saturday, September 22, 2012 1:16 AM
     
      Has Code

    After s1->swap(*s2) or std::swap(*s1,*s2);, s1 remain the same, 5000, not 6000.

    using std::swap;  at Father class

    i am following effective c++ book

    but i do not understand where it used below code

    namespace std{
    template<>
    void swap<Father>(Father& a, Father& b)
    {
    	a.swap(b);
    }
    }

    because even without above code, swap can be used to exchange shared_ptr. It means that there is a standard swap function. does above code override the swap in std ?

    when i change namespace std to namespace std2, then in father class use std2::swap, then it said

    std2 is not a standard class or namespace


    成全佢



    • Edited by zvzzvz Saturday, September 22, 2012 2:17 AM
    •  
  • Saturday, September 22, 2012 3:32 AM
     
     

    vNext2012 wrote:

    After s1->swap(*s2) or std::swap(*s1,*s2);, s1 remain the same, 5000,  not 6000.

    Why would you expect otherwise? Your swap() implementation never touches  'money' member. It only swaps pImpl, which is never initialized and  never used for anything anyway.

    because even without above code, swap can be used to exchange shared_ptr. It means that there is a standard swap function.

    Yes there is - otherwise, you wouldn't have been able to write a template specialization, as there would be nothing to specialize. The generic implementation works in terms of copy constructor and assignment operator, along the lines of

    template <typename T>
    void swap(T& a, T& b) {
        T temp(a);
        a = b;
        b = temp;
    }

    does above code override the swap in std ?

    Not override - specialize.


    Igor Tandetnik

    • Marked As Answer by zvzzvz Monday, September 24, 2012 1:10 AM
    • Unmarked As Answer by zvzzvz Monday, September 24, 2012 1:12 AM
    •  
  • Monday, September 24, 2012 1:10 AM
     
     

    success, after adding swap(money, other.money);

    as i found it start with b (from son), not c (from son2)

    it seems not swap their functions of instance

    so, what do swap(pImpl, other.pImpl); swap ?

    usually when to use template specialization?


    成全佢



    • Edited by zvzzvz Monday, September 24, 2012 2:56 AM
    •