I am trying to use a function template foo
to convert arguments to a initializer_list
. However, the initializer_list
it converted has strange values which are not the same as the input arguments.
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
using namespace std;
template<class T>
void func(std::initializer_list<T> a_args)
{
if (a_args.begin() != a_args.end())
{
auto last = prev(a_args.end());
copy(a_args.begin(), last, ostream_iterator<int>(cout, ","));
cout << *last;
}
cout << endl;
}
template<class T, class ...Args>
struct first_of
{
typedef T type;
};
template<class ...Args>
initializer_list<typename first_of<Args...>::type> foo(Args&&... args)
{
return { forward<Args>(args)... };
}
int main()
{
func({1,2,3});
auto x = foo(1,2,3);
func(x); //this should be the same as func({1,2,3}) but not.
}
LIVE CODE
The ouput is as follows:
1,2,3
-326483696,32767,0
What is wrong here?
std::initializer_list<T>
should only be used as a temporary object or function parameter, since it refers to a temporary array.
8.5.4/5-6:
An object of type
std::initializer_list<E>
is constructed from an initializer list as if the implementation allocated a temporary array of N elements of typeconst E
, where N is the number of elements in the initializer list. ...The array has the same lifetime as any other temporary object (12.2), except that initializing an
initializer_list
object from the array extends the lifetime of the array exactly like binding a reference to a temporary.
18.9/2:
An object of type
initializer_list<E>
provides access to an array of objects of typeconst E
. [Note: A pair of pointers or a pointer plus a length would be obvious representations forinitializer_list
.initializer_list
is used to implement initializer lists as specified in 8.5.4. Copying an initializer list does not copy the underlying elements.]
So returning an initializer_list
object is just as bad as:
struct int_ref {
int& ref;
explicit constexpr int_ref(int& r) : ref(r) {}
};
int_ref func() {
int n = 5;
return int_ref(n);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With