0

文字列を(特定の形式で)解析するための一般的なソリューションを考え出そうとしています。たとえば、数値 (整数または浮動小数点数) のリストを含む文字列を解析し、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関数の戻り値の型に基づいてテンプレート値を推測することに依存していることだと思います。これを修正する方法がよくわかりません(または、設計アプローチに完全に欠陥がある可能性があるため、修正できるかどうかさえも)。私がやろうとしていることを解決する方法を知っている人はいますか? 現在の実装で発生している問題に対処するための可能な方法を教えていただければ幸いです。ところで、私はこの問題を解決するためのまったく異なるアイデアにもオープンです。

4

2 に答える 2

1

戻り値[1]に基づいて関数をオーバーロードすることはできません。これが、標準IOライブラリが構成を使用する理由です。

std::cin >> a >> b;

これはあなたのケーキではないかもしれません-多くの人はそれを好きではありません、そしてそれは本当に問題がないわけではありません-しかしそれはパーサーにターゲットタイプを提供するという素晴らしい仕事をします。parse<X>(const std::string&)また、上記のように、静的プロトタイプに比べてチェーンとストリーミングが可能であるという利点もあります。それが必要ない場合もありますが、多くの構文解析コンテキストではそれが不可欠であり、の使用operator>>は実際にはかなりクールな構文です。[2]

scanf標準ライブラリは、文字列定数スタイルをスキップしてインターリーブされた読み取りを可能にするという、最もクールなことを実行しません。

vector<int> integers;
std::cin >> "[" >> interleave(integers, ",") >> "]";

ただし、それは定義できます。(文字列リテラルの周りに明示的なラッパーを使用する方が良いかもしれませんが、実際にはそのようにするのが好きです。ただし、変数を渡す場合はラッパーを使用する必要があります)。


[1]新しいauto宣言により、この理由はさらに明確になります。

[2]一方、IOマニピュレータは残酷なジョークです。そして、エラー処理は哀れです。しかし、すべてを手に入れることはできません。

于 2012-12-12T00:20:51.583 に答える