7

I've got a program which works in g++ and clang, using a nested initializer_list. In Visual C++, the 1D case works, but a 2D nested initializer_list does not. Is there a trick to make Visual C++ work, or is this maybe a bug in their implementation?

Here's my example code. It works in Visual C++ 2013 if I remove the annotated line.

#include <iostream>
#include <initializer_list>

using namespace std;

template<class T>
void print(T val) {
    cout << val;
}

template<class T>
void print(initializer_list<T> lst) {
    bool first = true;
    cout << "[";
    for (auto i : lst) {
        if (!first) cout << ", ";
        print(i);
        first = false;
    }
    cout << "]";
}

template<class T>
void print(initializer_list<initializer_list<T>> lst) {
    bool first = true;
    cout << "[";
    for (auto i : lst) {
        if (!first) cout << ", ";
        print(i);
        first = false;
    }
    cout << "]";
}

int main()
{
    print({1, 2, 3});
    cout << endl;
    // Without this line, Visual C++ 2013 is happy
    print({{1, 2}, {3, 4, 5}, {6}});
}
mwiebe
  • 275
  • 1
  • 7
  • 3
    VC++ is not standard-compliant. – Sergey Kalinichenko May 31 '14 at 01:37
  • 3
    Visual studio is the slow child of compilers. – Syntactic Fructose May 31 '14 at 01:51
  • 8
    VC's `initializer_list` implementation is buggy. See [this question](https://stackoverflow.com/questions/20165166/double-delete-in-initializer-list-vs-2013) and others under the linked questions on the right of that page. Your code is correct, and you've found yet another bug. You should report it on Microsoft Connect. – Praetorian May 31 '14 at 01:54
  • 4
    I've [reported the issue on microsoft connect](https://connect.microsoft.com/VisualStudio/feedback/details/884549/nested-initializer-list-does-not-work), thanks for the feedback! – mwiebe May 31 '14 at 02:50
  • @mwiebe It's been reported several times already. Have you already updated your VS2013 with Update1? AFAIK, this bug is already fixed. – polkovnikov.ph May 31 '14 at 11:04
  • @polkovnikov.ph : I have Update 2 installed and this code still fails to compile. – ildjarn May 31 '14 at 11:20
  • @polkovnikov.ph while my VS2013 wasn't up to date, I've now updated to Update 2 and can confirm it still fails as before. – mwiebe Jun 02 '14 at 06:19
  • @SyntacticFructose Visual Studio is "differently able". – Oktalist Jul 26 '14 at 18:17

1 Answers1

1
template<class T>
std::initializer_list<T> list( std::initializer_list<T>&& l ) { return std::move(l); }

or something similar may at least give you the workaround:

print( { list({1,2}), list({3,2,1}) } );

the syntax can be messed around with (l*{2,1}) in a few ways as well.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524