最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - How to create std::expected<void, void> to signal success or exception without any additional data? - Stack

programmeradmin2浏览0评论

Is it possible to create an object of type unexpected for a std::expected<void, void>?

Here's a simple example.

#include <expected>

[[nodiscard]]
std::expected<void, void> do_logic() {
    return std::unexpected<void>();
}

This does not compile, at least not with gcc-14.

error: no matching function for call to ‘std::unexpected<void>::unexpected()’

I am surprised that this code does not compile because the following does compile:

#include <expected>

[[nodiscard]]
std::expected<void, int> do_logic() {
    return std::unexpected<int>(-1);
}

Is there a way to make it work with <void, void>?

Intended Use

const auto result = do_logic();

if(result.has_value()) {
    // success case
}
else {
    // error case
}

Is it possible to create an object of type unexpected for a std::expected<void, void>?

Here's a simple example.

#include <expected>

[[nodiscard]]
std::expected<void, void> do_logic() {
    return std::unexpected<void>();
}

This does not compile, at least not with gcc-14.

error: no matching function for call to ‘std::unexpected<void>::unexpected()’

I am surprised that this code does not compile because the following does compile:

#include <expected>

[[nodiscard]]
std::expected<void, int> do_logic() {
    return std::unexpected<int>(-1);
}

Is there a way to make it work with <void, void>?

Intended Use

const auto result = do_logic();

if(result.has_value()) {
    // success case
}
else {
    // error case
}
Share Improve this question edited Mar 16 at 14:25 user2138149 asked Mar 14 at 22:23 user2138149user2138149 17.7k30 gold badges149 silver badges296 bronze badges 11
  • That would defeat the whole purpose of std::expected would it not? – Pepijn Kramer Commented Mar 15 at 4:05
  • 1 C++ provides a unit type, called std::monostate in <variant> (or <utility> in C++26), which you can use in std::expected<void, std::monostate>. It's like void in many respects, but it is instantiatable because it is a complete type. (It's much like an empty-tuple std::tuple<> or empty struct struct empty {}; or even single-valued std::nullptr_t, albeit it with some nicer properties and semantics than those others provide.) – Eljay Commented Mar 15 at 8:36
  • What about using bool? – PiotrNycz Commented Mar 15 at 18:01
  • @PiotrNycz There are numerous discussions available both here, elsewhere online, and in other resources (eg books) which argue at length why using return values is not a good design to handle exceptions. std::expected resolves this design problem. – user2138149 Commented Mar 16 at 14:24
  • It is true - but std::expected<void,void> - represents only one bit of information - ok/not-ok -- like bool. en.wikipedia./wiki/KISS_principle – PiotrNycz Commented Mar 16 at 15:38
 |  Show 6 more comments

1 Answer 1

Reset to default 1

You can't form the type std::unexpected<void> because

A program that instantiates the definition of unexpected for a non-object type, an array type, a specialization of unexpected, or a cv-qualified type is ill-formed.

https://eel.is/c++draft/expected.un.general#2

and

void is not an object type because

An object type is a (possibly cv-qualified) type that is not a function type, not a reference type, and not cv void.

https://eel.is/c++draft/basic.types#general-8

std::expected inherits the requirements of std::unexpected, therefore std::expected<?, void> is prohibited.

A program that instantiates the definition of the template expected<T, E> with a type for the E parameter that is not a valid template argument for unexpected is ill-formed.

https://eel.is/c++draft/expected.void#general-2

Since you can't form the type std::expected<void, void>, it is pointless to try to find return expressions compatible with that type.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论