Search code examples
c++11ofstreaminitializer-list

initializer_lists of streams (C++11)


I'm trying to pass variable number of ofstreams over to a function that accepts an initializer_list but doesn't seem to work and throws all possible errors from the initializer_list structure and about how my function is with an array of ofstreams cannot be matched to any defined function.

Is it actually possible to pass a reference of ofstreams over in an initializer_list?

test.cpp

#include "extension.h"


ofstream outputFile, outputFile2;

int main(void) {

    outputFile.open(("data_1.txt");
    outputFile2.open("data_2.txt");
    writeSomething({outputFile, outputFile2});
    outputFile.close();
    outputFile2.close();
}

extension.h

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <string.h>
#include <initializer_list>

using namespace std;

void writeSomething(initializer_list<ofstream&> args);

extension.cpp

#include "extension.h"

void writeSomething(initializer_list<ofstream&> args) {
    for (auto f : args ) {
        f << "hello" << endl;
    }
}

Solution

  • clang 3.4 (trunk 194324) produces a pretty clear error message:

    initializer_list:54:23: error: 'iterator' declared as a pointer to a reference of type
    'std::basic_ofstream<char> &'
    typedef const _E* iterator;

    So no, it is not possible. See also Error: forming pointer to reference type 'const std::pair&'… I can't understand this error.

    (gcc 4.7.2 and 4.8.1 crashes on this code due to some internal compiler error. I have submitted a bugreport.)

    What you could do instead is to pass a pointer instead of a reference, something like this:

    #include <fstream>
    #include <initializer_list>
    
    using namespace std;
    
    void writeSomething(initializer_list<ofstream*> args) {
        for (auto f : args )
            *f << "hello" << endl;
    }
    
    int main() {
        ofstream outputFile("data_1.txt");
        ofstream outputFile2("data_2.txt");
        writeSomething({&outputFile, &outputFile2});
    }
    

    However, I would much rather use a std::vector instead. Using an initializer list for this purpose is very strange and confusing for me.