3

signaturer を使用した C++11 関数を考えるとstd::regex_match( std::string const&, std::smatch& match, std::regex const& re )、最初の引数の有効期間に対する制約は何ですか? 何も見つかりませんが、次のプログラムを実行すると (VC++ 2010 でコンパイルされ、反復子のデバッグがアクティブになります):

int
main()
{
    std::string a("aaa");
    std::string c("ccc");
    std::regex re("aaa(.*)ccc");
    std::smatch m;
    if (std::regex_match(a + "xyz" + c, m, re)) {
        std::cout << m[0] << std::endl;
        std::cout << m[1] << std::endl;
    }
    return 0;
}

sub_matchinmはイテレータを文字列に保持するだけで、コピーは保持しないため、間違いなくクラッシュします。私のコードを禁止する標準には何も見つかりません。

FWIW: では機能しませんでした。boost::regexそれ std::regexがベースになっています。(もちろん、Boost は寿命に関する制約も文書化していません。)

最後に、私の質問は、DR を標準化団体に送るか、バグ レポートを Microsoft に送るかということだと思います。

4

2 に答える 2

3

tr1::regexまたはの採用時にこの可能性についての議論を覚えていないstd::regexので、単に考慮されていなかったと思います。後から考えると、それは確かに私たちが予見していたはずの罠です。私の頭のてっぺんから、std::string&&一時的なものが関係していて、コピーが必要であるというシグナルを受け取るオーバーロードが発生しました。だから私はそれを標準委員会に報告します。(完全な開示: Microsoft が出荷する Dinkumware 実装を作成しました)

于 2012-08-16T17:05:24.603 に答える
1

この過負荷の仕様では、次のようにregex_match述べられています(28.11.2 [re.alg.match] / 6):

戻り値: regex_match(s.begin(), s.end(), m, e, flags)

このオーバーロードには追加の要件はなく、委任先のオーバーロードはイテレータ範囲のみを取ります。保持する文字列があることすら知らないため、一時的な文字列を存続させる方法はありません。生きている。

この問題は、C ++Now'12でのSTLのregexプレゼンテーション中に議論されました。誰かが、右辺値の文字列引数(たとえば)をキャッチするために、仕様に追加のオーバーロードを追加することを推奨しましたbasic_string<...>&&。これにより、このランタイムエラーの代わりに素晴らしいコンパイルエラーが発生します。ただし、ライブラリの仕様にはこれらのオーバーロードは含まれていません。また、これに関する欠陥レポートは表示されません。

于 2012-08-16T17:08:26.177 に答える