25.2.5.1 Default Function Template Arguments
Naturally, default template arguments can also be useful for function templates. For example:
template
Targ et to(Source arg) // convert Source to Target
{
stringstream interpreter;
Targ et result;
if (!(interpreter << arg) // write arg into stream
|| !(interpreter >> result) // read result from stream
|| !(interpreter >> std::ws).eof()) // stuff left in stream?
throw runtime_error{"to<>() failed"};
return result;
}
A function template argument needs to be explicitly mentioned only if it cannot be deduced or if
there is no default, so we can write:
auto x1 = to<string,double>(1.2); // very explicit (and verbose)
auto x2 = to(1.2); // Source is deduced to double
auto x3 = to<>(1.2); // Target is defaulted to string; Source is deduced to double
auto x4 = to(1.2); // the <> is redundant
If all function template arguments are defaulted, the <> can be left out (exactly as in function tem-
plate specializations; §25.3.4.1).
This implementation of to() is a bit heavyweight for combinations of simple types, such as
to(int) , but improved implementations can be supplied as specializations (§25.3). Note that
to(int) will not work because char and int do not share a string representation. For conversion
among scalar numeric types, I tend to prefer narrow_cast<>() (§11.5).

感觉挺牛的,记录一下。

#include <iostream>
#include <sstream>
#include <stdexcept>
using namespace std;

template<typename Target=string, typename Source=string>
Target to(Source arg) {
  stringstream interpreter;
  Target result;
  if (!(interpreter << arg)
    || !(interpreter >> result)
    // || !(interpreter >> ws).eof()
    )
    throw runtime_error{"to<>() failed"};

  return result;
}

int main() {
    cout << to<int>("7") << endl; 
}
原文见 The C++ Programming Language 4th Edition 第 730 页
最后修改:2019 年 03 月 23 日
如果觉得我的文章对你有用,请随意赞赏