さまざまな戻り値の型を持つstd :: arrayのrecursive_transform

Oct 26 2020

これは、さまざまな戻り値の型を持つstd :: vectorのrecursive_transformのフォローアップ質問です。G. Sliepenに感謝し、さらなるレビューの提案を提供します。recursive_transformさまざまな出力タイプとさまざまなコンテナタイプの両方でより一般的な機能を実現するというトピックを掘り下げた後でも、簡単な解決策はまだありません。ただし、G。Sliepenの回答に基づいて、の場合std::vector、std::dequeおよびstd::listコンテナタイプが解決される場合があります。に追加の別のオーバーロードrecursive_transform関数を実装しようとしていstd::arrayます。これが私の実装です。

template<class T, std::size_t S, class F>
auto recursive_transform(std::array<T, S>& input, const F& f)
{
    using TransformedValueType = decltype(recursive_transform(*input.cbegin(), f));

    std::array<TransformedValueType, S> output;
    std::transform(input.cbegin(), input.cend(), output.begin(), 
        [f](auto& element)
        {
            return recursive_transform(element, f);
        }
    );
    return output;
}

のテストケースstd::array:

//  std::array<int, 10> -> std::array<std::string, 10>
std::array<int, 10> test_array;
for (int i = 0; i < 10; i++)
{
    test_array[i] = 1;
}
auto recursive_transform_result5 = recursive_transform(
    test_array,
    [](int x)->std::string { return std::to_string(x); });                          //  For testing
std::cout << "string: " + recursive_transform_result5.at(0) << std::endl;

これがGodboltリンクです。以下のためのテストケースを含む、このリンクのコードstd::vector、std::dequeおよびstd::list。

すべての提案を歓迎します。

要約情報:

  • フォローアップはどの質問ですか?

    さまざまな戻り値の型を持つstd :: vectorのrecursive_transform

  • 前回の質問以降、コードにどのような変更が加えられましたか?

    以前のバージョンのrecursive_transform関数で処理可能なコンテナタイプはstd:vectorです。G. Sliepenの答え、この取り扱い可能なコンテナ型のリストはに拡張されstd::vector、std::dequeそしてstd::list。それでは、std::arrayここで対処しようとしています。

  • なぜ新しいレビューが求められているのですか?

    このバージョンのrecursive_transform関数では、前述のテストケースでうまく機能しているようですstd::array<int, 10> -> std::array<std::string, 10>。ただし、std::array<std::array<int, 10>, 10> -> std::array<std::array<std::string, 10>, 10>(スケーラビリティが向上する!)のようなより複雑なケースに関しては、いくつかの問題があります。これについて何か提案や考えられるアイデアがあれば、私に知らせてください。

回答

1 G.Sliepen Oct 26 2020 at 20:37

const一貫して参照を渡すようにしてください

コードの主な問題は、std::arrayオーバーロードにconst参照によって入力を受け取らせなかったことです。

auto recursive_transform(std::array<T, S>& input, const F& f)

追加するだけconstです!ネストされたが機能しているこのGodboltリンクを参照してくださいstd::array。

std::begin()およびを使用することをお勧めしますstd::end()

標準ライブラリのコンテナのみをサポートするかどうかは重要ではありませんが、テンプレートを作成するときは、std::begin()andのstd::end()代わりに->begin()andを使用することをお勧めします->end()。利点は、あなたが提供していない非標準コンテナのどこかで使用している場合ということであるbegin()とend()メンバ関数を、まだ外のクラスのオーバーロードすることが可能となりますstd::begin()とstd::end()、そのクラスにイテレータのサポートを追加するための関数を。アルゴリズムテンプレートで使用する場合、アルゴリズムはこれらの非標準クラスもサポートします。