C++ Logo

std-proposals

Advanced search

Re: [std-proposals] attribute [[unevaluated]]

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Tue, 20 May 2025 13:12:41 +0100
On Tue, 20 May 2025 at 13:07, Frederick Virchanza Gotham via
Std-Proposals <std-proposals_at_[hidden]> wrote:
>
> On Tue, May 20, 2025 at 9:02 AM Jonathan Wakely wrote:
> >
> >
> > If the function body is empty then it can typically be a variable template or an alias template.
> > Or have no function body at all. You don't need to define it if you're not calling it.
>
>
> I didn't realise that my previous code would compile and link
> successfully without a body, that's cool.
>
> But then there's times when a body is needed, like in the following
> function. (Note in places that I had to use *((A*)nullptr) instead of
> 'declval' because the compiler refused to compile it). You can
> dereference a null pointer in a non-evaluated context, it's fine.
>
> #include <type_traits> // is_same, remove_cvref
> #include <utility> // declval
>
> template<class ExcludedTypezzz, class Azzz, class Bzzz, class Czzz>
> consteval decltype(auto) GetType(Azzz&&, Bzzz&&, Czzz&&) noexcept
> {
> using std::declval, std::is_same_v, std::remove_cvref_t;
>
> typedef remove_cvref_t<Azzz> A;
> typedef remove_cvref_t<Bzzz> B;
> typedef remove_cvref_t<Czzz> C;
> typedef remove_cvref_t<ExcludedTypezzz> ExcludedType;
>
> constexpr auto is_valid = []<typename ExcludedType2, typename
> T>(void) consteval noexcept -> bool
> {
> if constexpr ( !requires { declval<typename
> T::value_type2>(); } ) return false;
> else if constexpr ( is_same_v< typename T::value_type2,
> void > ) return false;
> else if constexpr ( is_same_v< typename T::value_type2,
> ExcludedType > ) return false;
> else return true;
> };
>
> if constexpr ( is_valid.template
> operator()<ExcludedType,A>() ) return *(A*)nullptr;
> else if constexpr ( is_valid.template
> operator()<ExcludedType,B>() ) return *(B*)nullptr;
> else if constexpr ( is_valid.template
> operator()<ExcludedType,C>() ) return *(C*)nullptr;
> else if constexpr ( requires { declval<A&>().begin(); } ) {
> return ((A*)nullptr)->begin(); }
> else if constexpr ( requires { declval<B&>().begin(); } ) {
> return ((B*)nullptr)->begin(); }
> else if constexpr ( requires { declval<C&>().begin(); } ) {
> return ((C*)nullptr)->begin(); }
> else
> {
> static_assert(false, "Wrong types!");
> }
> }
>
> #include <sstream> // ostringstream
> #include <string> // string
> #include <vector> // vector
>
> #include <iostream> // cout
>
> int main(void)
> {
> std::ostringstream ss;
> std::string s;
> std::vector<int> vec;
>
> typedef decltype(GetType<int>(ss,s,vec)) SomeType;
>
> std::cout << "Hi\n";
> }
>
> The above program compiles and runs fine.

Great, so you don't need any language change.

Received on 2025-05-20 12:12:57