Date: Thu, 22 May 2025 08:47:25 +0100
On Wed, May 21, 2025 at 12:54 AM Thiago Macieira wrote:
>
> decltype(std::declval<T (*)()>()())
That's clever. But every modern C++ compiler fails to compile the
following source file:
#include <string> // string
#include <utility> // declval
template<typename T>
decltype(auto) consteval Func(void) noexcept
{
return std::declval<T(*)(void)>()();
}
int main(void)
{
typedef decltype(Func<std::string>()) MyType;
}
The problematic line is the return statement from 'Func', as the
compiler thinks that the result of 'declval' is being used in an
evaluated context.
The solution, I think, is to apply an attribute to 'Func' as follows:
template<typename T>
[[unevalutated]] decltype(auto) consteval Func(void) noexcept
{
return std::declval<T(*)(void)>()();
}
This attribute will have two effects:
(1) It will disallow the compiler to call this function in an
evaluated context
(2) It will allow unrestricted use of "declval" inside the body of
the function
>
> decltype(std::declval<T (*)()>()())
That's clever. But every modern C++ compiler fails to compile the
following source file:
#include <string> // string
#include <utility> // declval
template<typename T>
decltype(auto) consteval Func(void) noexcept
{
return std::declval<T(*)(void)>()();
}
int main(void)
{
typedef decltype(Func<std::string>()) MyType;
}
The problematic line is the return statement from 'Func', as the
compiler thinks that the result of 'declval' is being used in an
evaluated context.
The solution, I think, is to apply an attribute to 'Func' as follows:
template<typename T>
[[unevalutated]] decltype(auto) consteval Func(void) noexcept
{
return std::declval<T(*)(void)>()();
}
This attribute will have two effects:
(1) It will disallow the compiler to call this function in an
evaluated context
(2) It will allow unrestricted use of "declval" inside the body of
the function
Received on 2025-05-22 07:47:38