template<class F> constexpr auto transform_error(F&& f) &; // (1)
template<class F> constexpr auto transform_error(F&& f) const &; // (2)
template<class F> constexpr auto transform_error(F&& f) &&; // (3)
template<class F> constexpr auto transform_error(F&& f) const &&; // (4)
概要
エラー値を保持していれば、エラー値に対してfを適用した結果をexpectedのエラー値として格納して返す。
正常値を保持していれば、そのまま返す。
実際には複数オーバーロードが提供されるが、大まかには下記シグニチャのようにみなせる。
transform_errorへは、引数リストに1個のE型をとりReturn型を返す関数や関数オブジェクトを与える。
template <class T, class E>
class expected {
template <class Return>
std::expected<T, Return> transform_error(function<Return(E)> func);
};
テンプレートパラメータ制約
- (1), (2) :
is_constructible_v<T, decltype(value())> == true - (3), (4) :
is_constructible_v<T, decltype(std::move(value()))> == true
適格要件
- (1), (2) : 型
Gをremove_cvref_t<invoke_result_t<F, decltype(error())>>としたとき、次を全て満たすことGがunexpectedの有効なテンプレート引数である- 宣言
G g(invoke(std::forward<F>(f), error()));が妥当である
- (3), (4) : 型
Gをremove_cvref_t<invoke_result_t<F, decltype(std::move(error()))>>としたとき、次を全て満たすことGがunexpectedの有効なテンプレート引数である- 宣言
G g(invoke(std::forward<F>(f), std::move(error())));が妥当である
効果
- (1), (2) : 次の効果をもつ
- (3), (4) : 次の効果をもつ
備考
transform_errorは、メソッドチェーンをサポートするモナド風(monadic)操作として導入された。
例
#include <cassert>
#include <algorithm>
#include <expected>
#include <string>
// 文字列を逆順に並べ替える関数
std::string revstr(std::string str)
{
std::reverse(str.begin(), str.end());
return str;
}
int main()
{
std::expected<int, std::string> v1 = 42;
assert(v1.transform_error(revstr).value() == 42);
std::expected<int, std::string> e1 = std::unexpected{"Oops"};
assert(e1.transform_error(revstr).error() == "spoO");
}
出力
バージョン
言語
- C++23
処理系
- Clang: ??
- GCC: 13.0 ✅
- ICC: ??
- Visual C++: ??
関連項目
参照
- P2505R5 Monadic Functions for
std::expected - LWG Issue 3866. Bad Mandates for
expected::transform_erroroverloads- C++23で、適格要件が「
Gがexpectedの有効なエラー値型である」から「Gがunexpectedの有効なテンプレート引数である」に修正された(const intのようにexpectedのエラー値型としては有効でもunexpectedのテンプレート引数としては無効な型があり、旧文言は実装不能だったため)
- C++23で、適格要件が「
- LWG Issue 3877. Incorrect constraints on
const-qualified monadic overloads forstd::expected- C++23で、
const修飾版で誤ってエラーになる問題を解消するため、制約がis_copy_constructible_v<T>からis_constructible_v<T, decltype(value())>(右辺値版はdecltype(std::move(value())))へ変更された
- C++23で、
- LWG Issue 3938. Cannot use
std::expectedmonadic ops with move-onlyerror_type