I know I can write
if (int a = 1; /* whatever */) {}
and even
if (int a = 1, b{3}; /* whatever */) {}
but how can I declare, say, a
of type int
and b
of type std::string
?
Such a thing doesn't work:
if (auto a = 1, b{"ciaos"s}; /* whatever */) {}
I've not included a standard, because I'm interested in the answer in general, even though realistically I'd make use of the answer in the context of c++17.
And, if such a thing is not possible, is there any precise reason why (hence language-lawyer)?
You are only allowed one variable declaration statement in a if statement and each variable declaration statement can only declare a single type. This is convered in [stmt.if]/3 where is shows the grammar for the if statement you are trying to use is
if constexpr(opt) ( init-statement condition ) statement
and init-statement
can be a simple-declaration
and that contains a init-declarator-list
which only allows a single declarator
. Normally this means just a single type, but pointers (*) and references (&) get applied to the variable name, not the type name so you can have T
, T*
, and/or T&
variables declared in a single init-declarator-list
i.e., int a = 42, *b = &a, &c = a;
As a workaround, you can leverage structured bindings and CTAD (to reduce verbosity) in conjunction with std::tuple
to get a syntax like
int main()
{
using namespace std::string_literals;
if (auto [a, b] = std::tuple{42, "string"s}; a)
{
std::cout << b;
}
}
which outputs
string