Search code examples
c++if-statementinitializationlanguage-lawyerdeclaration

Can I initialize object of different types in an if statement?


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 .

And, if such a thing is not possible, is there any precise reason why (hence )?


Solution

  • 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