2

私は、一部のコードを変更してQStringBuilder式テンプレートを利用し、パフォーマンスを向上させることを検討しています。残念ながら、これにより、コードのセクションがいくつかの場所でクラッシュし始めました。その例を次に示します。

#define QT_USE_QSTRINGBUILDER
#include <numeric>
#include <vector>
#include <QString>
#include <QStringBuilder>

int main()
{
    std::vector<int> vals = {0, 1, 2, 3, 4};
    QString text = "Values: " + QString::number(vals[0]);
    text = std::accumulate(vals.begin() + 1, vals.end(), text, [](const QString& s, int i)
    {
        return s + ", " + QString::number(i);
    });
}

これがクラッシュする理由は、ラムダ式の戻り値の型が、QStringBuilder<QStringBuilder<QString,const char [3]>,QString>返された後にキャストしQStringて結果に代入しようとするものであると推定されるaccumulateためです。このキャストは、ラムダのスコープ内にあり、現在破棄されているオブジェクトへの参照を使用しようとしているため、クラッシュします。このクラッシュは、ラムダの戻り値の型を明示的に指定することで修正できます[](const QString& s, int i) -> QString。これにより、クロージャーが終了する前にキャストが発生することが保証されます。

ただし、QStringBuilderここで有効にすると、以前は機能していたコードが警告を発することなくクラッシュしたという事実は、これが再び発生しないことを保証できない限り、他の場所での使用を避けることを意味します。この場合、RVO はコピーの発生を防ぐことができるため、オブジェクトのコピーを無効にする通常の手法は機能しないと思います。QStringBuilderこれがまたは同様の式テンプレートで発生するのを防ぐ方法はありますか、または自動変数への参照を維持するオブジェクトは常に安全に使用できませんか?

4

2 に答える 2

0

ラムダは明示的な型を返す必要があります。

[]() -> Type { }

or 

[]() -> QString { }
于 2015-09-09T14:59:53.180 に答える