我需要编写一个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
接口,如下所示,并在此功能上重载。
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);
答案 0 :(得分:1)
您可以使用支持partial template specialization的类模板;虽然功能模板不适用。 e.g。
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>>("");
答案 1 :(得分:0)
即使参数相同,您也可以重载功能模板,所以只需使用
即可// overloading, not specialization
template <typename T, typename U>
std::pair<T, U> parse(const std::string &s);