Simplify noexcept specifier + trailing return type + function body

Viewed 65

Imagine writing some generic code:

template<class...Args>
auto do_something(Args&&...args)
        noexcept(noexcept(detail::do_something(std::forward<Args>(args)...)))
        -> decltype(detail::do_something(std::forward<Args>(args)...))
{
    return detail::do_something(std::forward<Args>(args)...);
}

I have to repeat the long expression of detail::do_something(std::forward<Args>(args)...) three times.

noexcept specifier is needed to propagate noexcept-ness.

Trailing return type is needed because many standard type traits and concepts (e.g. invocable-families) need to know the return type in immediate context.

I know that this could be worked around by macros. But is there any C++ way to simplify it or any existing work that might help to simplify it in the future?

For example, there's an answer written in 2015 that mentioned a proposal introducing noexcept(auto) but still being at status of "Do we think the valid and reasonable uses of noexcept(auto) are important enough that we should standardize it?".

1 Answers

There is currently no language support for this in the standard other than using macro. However, you can use BOOST_HOF_RETURNS from Boost.HOF to avoid duplicating expressions

#include <boost/hof/returns.hpp>

namespace detail {
  template<class...Args>
  decltype(auto) do_something(Args&&...args);
};

template<class...Args>
auto do_something(Args&&...args)
  BOOST_HOF_RETURNS(
    detail::do_something(std::forward<Args>(args)...))

Demo

Related