Date: Wed, 25 Mar 2026 00:02:13 +0000
I've heard C++ described a few times as "hacks upon hacks". Given that
we can make things deprecated in future standards, there is
opportunity to remedy some of these hacks.
I've jotted down a few of these hacks, and here's the first one:
decltype(x) Vs decltype( (x) )
I think 'decltype' should be replaced with two separate operators:
vartype (get the type of a variable)
exprtype (get the type of an expression)
Currently we achieve the distinction between the above two by using
either one set or two sets of parentheses with 'decltype', which is
kind of hacky.
In C++29, 'decltype' could be marked deprecated and the above two
operators could be added as its replacement.
By the way the operator 'vartype' could also be used to determine if
something is a variable:
if constexpr( requires { vartype(var) } ) cout << "yes it's a variable\n";
When the return type of a function is specified as 'decltype(auto)',
it uses the 'decltype' rules on the return operand. That means that
these two differ:
static int x;
decltype(auto) f(void)
{
return x;
}
decltype(auto) g(void)
{
return (x);
}
The first returns 'int', while the second returns 'int&'. So in C++29
they could become:
static int x;
vartype(auto) f(void)
{
return x;
}
exprtype(auto) g(void)
{
return x;
}
Now let's take a look at a more obscure function as follows:
template<typename T>
decltype(auto) Func(void)
{
static T x;
if constexpr ( is_polymorphic_v<T> )
return x;
else
return (x);
}
Here, the deduced return type depends on the 'decltype(x)' versus
'decltype((x))' distinction:
for polymorphic T: T
otherwise: T&
If C++ were to replace 'decltype' with 'vartype' and 'exprtype', then
functions such as 'Func' above would no longer fit cleanly into either
category. This is exactly the kind of subtle semantic dependence on
parenthesisation that should be removed from the language. Accordingly
'Func' would become ill-formed and unimplementable.
I think this would make the language clearer, more sensible, and
easier to teach.
P.S. . . . If you're really hellbent on writing 'Func' then you would
have to do:
template<typename T>
conditional_t< is_polymorphic_v<T>, T, T& > Func(void)
{
static T x;
return x;
}
we can make things deprecated in future standards, there is
opportunity to remedy some of these hacks.
I've jotted down a few of these hacks, and here's the first one:
decltype(x) Vs decltype( (x) )
I think 'decltype' should be replaced with two separate operators:
vartype (get the type of a variable)
exprtype (get the type of an expression)
Currently we achieve the distinction between the above two by using
either one set or two sets of parentheses with 'decltype', which is
kind of hacky.
In C++29, 'decltype' could be marked deprecated and the above two
operators could be added as its replacement.
By the way the operator 'vartype' could also be used to determine if
something is a variable:
if constexpr( requires { vartype(var) } ) cout << "yes it's a variable\n";
When the return type of a function is specified as 'decltype(auto)',
it uses the 'decltype' rules on the return operand. That means that
these two differ:
static int x;
decltype(auto) f(void)
{
return x;
}
decltype(auto) g(void)
{
return (x);
}
The first returns 'int', while the second returns 'int&'. So in C++29
they could become:
static int x;
vartype(auto) f(void)
{
return x;
}
exprtype(auto) g(void)
{
return x;
}
Now let's take a look at a more obscure function as follows:
template<typename T>
decltype(auto) Func(void)
{
static T x;
if constexpr ( is_polymorphic_v<T> )
return x;
else
return (x);
}
Here, the deduced return type depends on the 'decltype(x)' versus
'decltype((x))' distinction:
for polymorphic T: T
otherwise: T&
If C++ were to replace 'decltype' with 'vartype' and 'exprtype', then
functions such as 'Func' above would no longer fit cleanly into either
category. This is exactly the kind of subtle semantic dependence on
parenthesisation that should be removed from the language. Accordingly
'Func' would become ill-formed and unimplementable.
I think this would make the language clearer, more sensible, and
easier to teach.
P.S. . . . If you're really hellbent on writing 'Func' then you would
have to do:
template<typename T>
conditional_t< is_polymorphic_v<T>, T, T& > Func(void)
{
static T x;
return x;
}
Received on 2026-03-25 00:02:28
