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
Post a Comment