Author Topic: Explanation of c++ explicit specialization templates,instantiations and stuff  (Read 1524 times)

0 Members and 1 Guest are viewing this topic.

pllaybuoy

  • Guest
This is my second contribution to the evilzone community , i asked this question myself the previous day and me hell sure many other c++ coders would be confused too in it afterall , so i couldn't find anybody to help me ,instead i banged my head many times and finally got the answer , so just a little explanation to the others about it
MAKE SURE YOU KNOW ABOUT FUNCTIONS AND A LITTLE ABOUT GENERIC TYPE FUNCTIONS IN C++

okay so just a structure i will be using in the below example
Code: [Select]
struct userinfo( std::string name; int age;);
                                   
 explicit specialization is making a function template for a particular type , that is you mention the type of arguments to be used with the function EXPLICITLY in the function prototype and definition
Code: [Select]
template <typename whatever> //function for generic type
void swap(whatever&a,whatever&b){
whatever temp;
temp=a;
a=b;
b=temp:}
the above is a function template for generic type means any type of integers could be used while calling the function and the compiler will use them .the function will work for every type but suppose you want to change the second element of a structure with another , there comes explicit SPECIALIZATION to the rescue
Code: [Select]
template <> void swap<userinfo>(userinfo &a ,userinfo &b){
int temp=a.age;
a.age=b.age;
b.age=temp;}

the above is explicit specialization for a structure (userinfo) , that is if the compiler reaches the call to the swap function with userinfo type arguments then it will go with the explicitly specialized definition of the function .

instantiations on the other hands are CALLS to the function defined before , you can NOT use an EXPLICIT INSTANTIATION with an EXPLICITLY SPECIALIZED function

like calling the generic function template(Swap) this way

double a=2;
double b=3;
swap(a,b);
is an example of IMPLICIT instantiation means you call the function without mentioning what type of variables you are using as arguments .
EXPLICIT instantiation on the other hand is the call to a generic function template , in such a call you mention that what type of variables you are using suppose the following
swap <int>(a,b);
the above is an EXPLICIT instantiation means the CALL to the generic function in which you mention  that both the variables are INT and must be treated the way INT are treated .
however you can't explicitly instantiate an EXPLICITLY SPECIALIZED TEMPLATE
*phew had to bang my hard many times just to digest this :/ , cheers everybody ,thanks for the support*


-regards
MR KHAN :D

Offline Xires

  • Noob Eater
  • Administrator
  • Knight
  • *
  • Posts: 379
  • Cookies: 149
    • View Profile
    • Feed The Trolls - Xires
Some of your theory is sound, but there's a little bit of lacking information.

Instantiation is the process of creating an 'instance' of an object.  Essentially, it refers to the definition of a variable and a call to that variable's type's constructor.  Basic example:

Code: (cpp) [Select]
struct userinfo {
    std::string name;
    int age;
};

class user {
  private:
    // private variables
    struct userinfo _ui;
    static unsigned int _count;

  public:
    // constructors
    user(std::string&, int&);
    user(struct userinfo&);


    // destructor
    ~user(void);

    // mutators(aka 'getters'/'setters')
    std::string Name(void) const;
    std::string Name(std::string&);

    int Age(void) const;
    int Age(int&);

    // public methods
    unsigned int Count(void) const;
};

user::user(std::string &n, int &a) {
    _ui.name = n;
    _ui.age = a;


    ++_count;
}


user::user(struct userinfo &ui) {
    _ui = ui;


    ++_count;
}


user::~user(void) {
    --_count;
}


std::string user::Name(void) const {
    return _ui.name;
}


std::string user::Name(std::string &n) {
    return (_ui.name = n);
}


int user::Age(void) const {
    return _ui.age;
}


int user::Age(int &a) {
    return (_ui.age = a);
}


unsigned int user::Count(void) const {
    return _count;
}


template <typename T> void doSwap(T &a, T &b) {  // basic template; this one swaps two generic data types
    T t = a;


    a = b;
    b = t;


    return;
}


/* Because class 'user' has a static variable contained therein which tracks the number of instances that exist globally
 * we should avoid anything that may try to actually instantiate a new object of that type.  Thus, we come up with an
 * alternate approach to swapping two objects of type 'user'.
 */
template <> void doSwap<user>(user &a, user &b) {  // template specialization
    struct userinfo t;


    t.name = a.Name();
    t.age = a.Age();


    a.Name(b.Name());
    a.Age(b.Age());


    b.Name(t.name);
    b.Age(t.age);


    return;
}


int main(void) {
    struct userinfo uiA = { "Alice", "36"};    // declare & define a variable called "uiA"
    struct userinfo uiB;                                 // declare but do not yet define
    user uA = user("Alice", "36");               // declare a variable of type 'user' called "uA" and instantiate is an object of that type
    user uB;                                                   // declare a variable of type 'user' called "uB" but do not yet instantiate it


    uiB.name = "Bob";                                 // initialize part of variable 'uiB'
    uiB.age = "41";                                       /* initialize the rest of variable 'uiB'; the 'uiB' variable is now "defined" as it now has
                                                                       * both name(which is "uiB") and value(which is 'Bob' & '41')
                                                                       */
    uB = user(uiB);                                           // this calls the 'user' object's constructor, thus creating an 'instance' of type 'user' as variable 'uB'


    doSwap<struct userinfo>(uiA, uiB);            // call the normal 'doSwap()' template
    doSwap<user>(uA, uB);                            // call the specialized 'doSwap()' template


    return 0;
}

-Xires

pllaybuoy

  • Guest
Yes the term is about objects which are instances of classes , but since this was about function templates so I concentrated more on that .
And btw dude I have not reached on the OOP part of C++yet, I am learning it by my own from ebooks I found so  this was my last chapter about functions and now the rest 7 are about OOP (From introduction to advanced), so I don't really get this code about classes , constructors and destructors ,btw I would be asking more questions so be ready lol
-cheers
« Last Edit: October 11, 2012, 09:58:58 pm by pllaybuoy »

Offline Xires

  • Noob Eater
  • Administrator
  • Knight
  • *
  • Posts: 379
  • Cookies: 149
    • View Profile
    • Feed The Trolls - Xires
You are welcome to ask any questions that you might have.  I'm sorry that the code I presented earlier was too advanced.  I hadn't considered that to be an issue.  I have been coding in C++ for a very long time so I don't often consider that people don't understand the code that I provide.
-Xires