Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding to initializer_list accepted by g++, but rejected by clang

The following code is accepted by g++ (14.2.1):

#include <vector>

template<typename T>
void foo(T i, std::vector<int> &v = {})
{  }

int main()
{
    std::vector<int> v;
    foo(3, v);
}

but rejected by clang (19.1.7) with:

non-const lvalue reference to type 'std::vector<int>' cannot bind to an initializer list temporary

If I rely on the default argument (by omitting the 2nd parameter), both compilers reject the code, which makes sense since an attempt is made to bind a non-const lvalue reference to an rvalue.

Is clang correct by rejecting the code or is g++ correct by accepting the code?

like image 928
Tootsie Avatar asked Nov 14 '25 22:11

Tootsie


1 Answers

Default arguments of function templates are not instantiated until used by a call expression ([temp.inst]/12). In your case there is no use of the default argument since when you call foo, you explicitly provide a second argument.

Because this default argument can never be valid, a compiler is permitted, but not required, to diagnose it when it is not instantiated ([temp.res.general]/6.1).

Note that we have some weasel wording in the standard that says that default arguments are considered as independent definitions in some sense ([temp.decls.general]/3), which is intended to allow rules like the above to apply to them.

like image 193
Brian Bi Avatar answered Nov 17 '25 10:11

Brian Bi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!