c++parametersreference

vector reference parameter with braces initialization. why it works?


I understand about the reference type with l-value that it should have address.

But, I don't understand why it works.

I think {1} is r-value, but it works correctly..

void func(const vector<int>& v)
{
    ;
}

int main()
{
    func({ 1 });

    return 0;
}

Solution

  • { 1 } is not an expression at all. It doesn't have any value category or type.

    Braces { /*...* } in a function argument simply mean that the parameter shall be initialized as if by = { /*...*/ } in a variable definition.

    So all it means is that the initialization of the parameter will happen exactly as if you wrote

    const vector<int>& v = { 1 };
    

    And this works, because the initialization rules for const lvalue references permit creating a temporary object to which the reference may be bound.

    So this is (almost) equivalent to

    const vector<int> unnamed = { 1 };
    const vector<int>& v = unnamed;
    

    where unnamed is a temporary object without name and with lifetime extended until the end of the full-expression in which the function call happens.


    I understand about the reference type with l-value that it should have address.

    Every object in C++, even if it is a temporary object, has an address. It is not a good idea to think about lvalue references as something that can only bind to something with an address. A reference can always bind to any object of a compatible type. There is nothing about an object that makes it "lvalue" or "rvalue" or differentiating it by whether or not it has an address.

    The rules about which value category an expression must have to be usable to initialize a reference are purely syntactical and in principle arbitrary language design decisions. And in particular the decision made for C++ is that a non-const lvalue reference is not permitted to be initialized by an rvalue expression, while a const lvalue reference may, even if that necessitates creating a temporary object to bind to.