Info
-
Did you know that C++17 [[nodiscard]] attribute can be applied not only to function?
Example
struct foo {
[[nodiscard]] foo(auto& resource) {}
};
struct [[nodiscard]] bar {};
auto fn() -> bar;
[[nodiscard]] auto fn2() -> bool;
int main(int, char** argv){
foo{argv}; // ignoring temp created by [[nodiscard]]
fn(); // ignoring return value with [[nodiscard]]
fn2(); // ignoring return value with [[nodiscard]]
}
Puzzle
-
Can you mark all provided types/functions as [[nodiscard]] and handle the consequenes?
- Do you know any production use cases when applying nodiscard for non-functions improves the code?
// TODO: mark nodiscard
struct foo { };
auto fn1() -> foo;
auto fn2() -> bool;
int main() {
// TODO: handle nodiscard
foo();
fn1();
fn2();
}
Solutions
struct [[nodiscard]] foo { };
[[nodiscard]] auto fn1() -> foo;
[[nodiscard]] auto fn2() -> bool;
int main() {
(void)foo();
(void)fn1();
(void)fn2();
}
struct [[nodiscard]] foo { };
[[nodiscard]] auto fn1() -> foo;
[[nodiscard]] auto fn2() -> bool;
int main() {
std::ignore = foo();
std::ignore = fn1();
std::ignore = fn2();
}
struct [[nodiscard]] foo { };
[[nodiscard]] auto fn1() -> foo;
[[nodiscard]] auto fn2() -> bool;
int main() {
auto not_ignored = foo();
auto not_ignored1 = fn1();
auto not_ignored2 = fn2();
}
struct [[nodiscard]] foo { };
[[nodiscard]] auto fn1() -> foo;
[[nodiscard]] auto fn2() -> bool;
int main() {
[[maybe_unused]] auto f = foo{};
(void) fn1();
ignore = fn2();
}
struct [[nodiscard]] foo {};
auto fn1() -> foo;
[[nodiscard]] auto fn2() -> bool;
int main() {
std::ignore = foo();
std::ignore = fn1();
std::ignore = fn2();
}
struct [[nodiscard]] foo { };
[[nodiscard]] auto fn1() -> foo;
[[nodiscard]] auto fn2() -> bool;
int main() {
static_cast<void>(foo());
[[maybe_unused]] foo Ω = fn1();
std::ignore = fn2();
}
struct [[nodiscard("Attribute 1")]] foo { };
[[nodiscard("Attribute 2")]] auto fn1() -> foo;
[[nodiscard("Attribute 3")]] auto fn2() -> bool;
int main() {
// TODO: handle nodiscard
static_cast<void>(foo());
static_cast<void>(fn1());
auto or_this = fn2();
}
struct [[nodiscard]] foo {};
auto fn1() -> foo;
[[nodiscard]] auto fn2() -> bool;
int main() {
// TODO: handle nodiscard
static_cast<void>(foo());
static_cast<void>(fn1());
static_cast<void>(fn2());
}