我需要写一个 parse
可以解析 string
的函数其他类型:
OtherType parse(const std::string &s)
由于 C++ 不允许通过返回值重载,我尝试使用模板和模板特化:
template <typename T>
T parse(const std::string &s);
template <>
double parse(const std::string &s) { return std::stod(s); }
这行得通,但是,我还需要使用 template <typename T, typename U> std::pair<T, U>
专门化此功能和 template <typename ...Args> std::tuple<Args...>
.显然,以下不会起作用:
template <>
template <typename T, typename U>
std::pair<T, U> parse(const std::string &s);
我不想修改parse
接口(interface)如下,并重载该函数。
template <typename T>
void parse(const std::string &s, T &t);
为了保留界面,我尝试了以下方法:
template <typename ...>
struct Trait {};
double parse_impl(Trait<double>, const std::string &s);
template <typename T, typename U>
std::pair<T, U> parse_impl(Trait<std::pair<T, U>>, const std::string &s);
template <typename T>
T parse(const std::string &s) {
return parse_impl(Trait<T>(), s);
}
虽然这很好用,但我想知道有没有更好的解决方案?有没有语法糖可以帮助我写出类似这样的东西:template <> template <typename T, typename U> std::pair<T, U> parse(const std::string &s);
最佳答案
您可以使用支持partial template specialization 的类模板;而函数模板则没有。例如
template <typename T>
struct parser {
static T parse(const std::string &s);
};
template <>
struct parser<double> {
static double parse(const std::string &s) {
return std::stod(s);
}
};
template <typename T, typename U>
struct parser<std::pair<T, U>> {
static std::pair<T, U> parse(const std::string &s) {
return ...;
}
};
template <typename... Args>
struct parser<std::tuple<Args...>> {
static std::tuple<Args...> parse(const std::string &s) {
return ...;
}
};
并添加辅助函数模板,
template <typename... T>
inline auto parse(const std::string& s) {
return parser<T...>::parse(s);
}
并将它们用作,
parse<double>("");
parse<std::pair<int, int>>("");
parse<std::tuple<int, int, int>>("");
关于c++ - 使用模板类专门化模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49557413/