samedi 11 avril 2020

why is specialised template being called?

I created a template called debug which is indirectly invoked through the function errorMsg. I then specialised the template to account for char * (code w/comments below hopefully helps with explanations)

After some playing around I was surprised that even though I defined the template specialisations at a point after they're called in errorMsg(), they were still being used.

I would have assumed because it had not yet been defined at the point the main template would instantiate a default copy or an error would occur

Any help resolving this issue would be great thanks

#include  "header.h"
int main()
{

    //std::vector<std::string> s_vec{"abc","cede","rfind"};
    int i = 3;
    int *j = &i;
    errorMsg(std::cout,"hey"); //<---calls debug
}


//defined specialisations after its invoked inside errorMsg
template <>
inline std::string debug(char * p)
{
    std::cout<<"specialsed char"<<std::endl;
    return debug(std::string(p));
}

template <>
inline std::string debug(const char *p)
{
    std::cout<<"specialised const char"<<std::endl;
    return debug(std::string(p));

(header.h)

#include <iostream>
#include <sstream>
#include <string>

//(1)
template <typename T>
std::string debug(const T&s)
{   
    std::cout<<"unspecialised obj"<<std::endl;
    std::ostringstream oss;
    oss<<s;
    return oss.str();
}

//(2)
template <typename T>
std::string debug(T *ptr)
{   
    std::cout<<"unspecialised raw ptr"<<std::endl;
    std::ostringstream oss;
    oss << "pointer: "<<ptr;
    if (ptr)
    {   
        oss<<" "<<debug(*ptr);
    }
    else
        oss<<" null pointer";

    return oss.str();
}

template <typename T, typename... Args> void print(std::ostream &os,const T &t,const Args&...rest);
template <typename T> std::ostream &print(std::ostream &os, const T &t);


template <typename... Args>
void errorMsg(std::ostream &os,Args &&...args)
{
    print(os,debug(std::forward<Args>(args))...); //debug called here
}

template <typename T>
std::ostream &print(std::ostream &os, const T &t)
{
    return os<<t<<std::endl;
}

template <typename T, typename... Args>
void print(std::ostream &os,const T &t,const Args&...rest)

{
    os<<t<<", ";
    print(os,rest...);
}

result:

specialised const char
unspecialised obj
hey

Aucun commentaire:

Enregistrer un commentaire