文字列を(特定の形式で)解析するための一般的なソリューションを考え出そうとしています。たとえば、数値 (整数または浮動小数点数) のリストを含む文字列を解析し、std::vector を返すことができるようにしたいと考えています。これは私がこれまでに持っているものです:
template<typename T, typename U>
T parse_value(const U& u) {
throw std::runtime_error("no parser available");
}
template<typename T>
std::vector<T> parse_value(const std::string& s) {
std::vector<std::string> parts;
boost::split(parts, s, boost::is_any_of(","));
std::vector<T> res;
std::transform(parts.begin(), parts.end(), std::back_inserter(res),
[](const std::string& s) { return boost::lexical_cast<T>(s); });
return res;
}
さらに、他のタイプの値を含む文字列を解析できるようにしたいと考えています。例えば:
struct Foo { /* ... */ };
template<>
Foo parse_value(const std::string& s) {
/* parse string and return a Foo object */
}
関数の単一の「階層」を維持する理由parse_value
は、boost::optional を使用してオプションの値 (存在するかどうかに関係なく) を解析したい場合があるためです。理想的には、対応する関数parse_optional_value
に委任する関数を1 つだけにしたいと思います。parse_value
template<typename T>
boost::optional<T> parse_optional_value(const boost::optional<std::string>& s) {
if (!s) return boost::optional<T>();
return boost::optional<T>(parse_value<T>(*s));
}
これまでのところ、私の現在のソリューションは機能しません (コンパイラは使用する正確な関数を推測できません)。問題は、私の解決策がparse_value
関数の戻り値の型に基づいてテンプレート値を推測することに依存していることだと思います。これを修正する方法がよくわかりません(または、設計アプローチに完全に欠陥がある可能性があるため、修正できるかどうかさえも)。私がやろうとしていることを解決する方法を知っている人はいますか? 現在の実装で発生している問題に対処するための可能な方法を教えていただければ幸いです。ところで、私はこの問題を解決するためのまったく異なるアイデアにもオープンです。