c++ - How to design and implement function template specialization properly? -


i want implement read functions std::ifstream. needs separate between pod type , others. (currently std::string)

template <typename t, typename = std::enable_if<std::is_pod<t>::value>::type> t read(std::ifstream& fin);  template <> std::string read<std::string, void>(std::ifstream& fin);  int main() {     std::ifstream fin("test", std::ios::binary);     int x = read<int>(fin);     std::string str = read<std::string, void>(fin); } 

i want remove 'void' template argument when invoke read std::string. how can it?

thanks in advance.


update(2017/09/14)

i got hint ec++ , tried implement following codes.

    template <bool b>     struct is_fundamental {         enum { value = b };     };      template <typename t>     static t doread(std::ifstream& fin, is_fundamental<true>);      template <typename t>     static t doread(std::ifstream& fin, is_fundamental<false>);      template <>     static std::string doread<std::string>(std::ifstream& fin, is_fundamental<false>);      template <typename t>     static t read(std::ifstream& fin) {         return doread<t>(fin, is_fundamental<std::is_fundamental<t>::value>());     }       int main()     {         std::string filename("./test.dat");         std::ifstream fin(filename, std::ios::binary);          read<int>(fin);         read<std::string>(fin);         read<std::vector<int>>(fin);          return 0;     } 

invoking each read<> gets proper function!

the problem isn't possible partial specialize function.

what use of structs?

if write read ad follows,

template <typename t> struct read   {    template <typename u = t>    typename std::enable_if<std::is_same<u, t>::value                          && std::is_pod<t>::value, t>::type       operator() (std::ifstream & fin)     { /* something; return t */ }  };  template <> struct read<std::string>  {    std::string operator() (std::ifstream & fin)     { /* something; return string */ }  }; 

you have generic version of read struct, operator() enabled of template type pod, , specialized version std::string (and can add other specializations of read; partial specialization also).

the drawback have change call of read() in way

int x = read<int>{}(fin); std::string str = read<std::string>{}(fin); 

that is, defining object (read<t>{}).

if prefer use static member inside read -- example, func() -- can avoid need of object creation have call in way

int x = read<int>::func(fin); std::string str = read<std::string>::func(fin); 

the following full working example

#include <vector> #include <fstream> #include <iostream> #include <type_traits>  template <typename t> struct read   {    template <typename u = t>    typename std::enable_if<std::is_same<u, t>::value                          && std::is_pod<t>::value, t>::type       operator() (std::ifstream & fin)     { t ret ; std::cout << "pod!" << std::endl ; fin >> ret ; return ret; }  };  template <> struct read<std::string>  {    std::string operator() (std::ifstream & fin)     { std::string ret ; std::cout << "string!" << std::endl; fin >> ret ;       return ret; }  };  int main()  {    std::ifstream fin("test", std::ios::binary);    int x = read<int>{}(fin);                    // write pod!    std::string str = read<std::string>{}(fin);  // write string!    //auto read<std::vector<int>>{}(fin);        // compilation error  } 

Comments

Popular posts from this blog

resizing Telegram inline keyboard -

command line - How can a Python program background itself? -

php - "cURL error 28: Resolving timed out" on Wordpress on Azure App Service on Linux -