Archived

This forum has been archived. Please start a new discussion on GitHub.

ifstream question

Hi!

I am trying to compute the size of a file in an ICE server, like this:


using namespace std;
...
ifstream file (path, ios::in|ios::binary);
...


The compiler complains with

Server.cpp:23: error: variable `std::ifstream file' has initializer but incomplete type

This code is from a C++ tutorial. Should I initialize an ifstream in another way when using ICE?

Thanks,
Catalin

Comments

  • This really has nothing to do with Ice. (We don't touch anything that would relate to standard IOstreams.)

    Your code looks correct to me -- does it work if you do this in a file that doesn't include any Ice headers?

    Cheers,

    Michi.
  • xdm
    xdm La Coruña, Spain
    I think that you are missing same std header in your code
  • xdm: I don't really know what you mean. 'ifstream' is expanded to 'std::ifstream', as shown in the error message.

    michi: No, it doesn't work. I am using gcc 3.3, because that is what they installed at school. I guess they changed something from version 3.2 to version 3.3.

    I'll try to find a machine with gcc 3.2 and try it out on it.

    Catalin
  • xdm
    xdm La Coruña, Spain
    I meand that you forget this includes in your code

    #include <fstream>
    #include <ios>
    #include <iostream>

    try with it
  • Thanks xdm,

    I was afraid you would say that. I tried it before. With the following #includes

    #include <Ice/Ice.h>
    #include <dacapo.h>
    #include <FileTransfer.h>

    #include <fstream>
    #include <ios>
    #include <iostream>


    I get the following compilation output:

    assoro: dacapo6>make server
    c++ -I. -I/hom/catalin/hfag/sysInstall/ice120/include -c dacapo.cpp Server.cpp FileTransfer.cpp
    Server.cpp: In member function `virtual int FileTransferI::getFileSize(const
    std::string&, const Ice::Current&)':
    Server.cpp:30: error: no matching function for call to `
    std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(const
    std::basic_string<char, std::char_traits<char>, std::allocator<char> >&,
    std::_Ios_Openmode)'
    /store/include/c++/3.3/iosfwd:89: error: candidates are:
    std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(const
    std::basic_ifstream<char, std::char_traits<char> >&)
    /store/include/c++/3.3/fstream:519: error:
    std::basic_ifstream<_CharT, _Traits>::basic_ifstream(const char*,
    std::_Ios_Openmode = std::ios_base::in) [with _CharT = char, _Traits =
    std::char_traits<char>]
    /store/include/c++/3.3/fstream:504: error:
    std::basic_ifstream<_CharT, _Traits>::basic_ifstream() [with _CharT = char,
    _Traits = std::char_traits<char>]
    Server.cpp: In member function `virtual int ApplicationI::run(int, char**)':
    Server.cpp:91: error: cannot allocate an object of type `FileTransferI'
    Server.cpp:91: error: because the following virtual functions are abstract:
    FileTransfer.h:203: error: virtual dacapo::FileBlock
    dacapo::FileTransfer::getFile(const std::string&, int, int, const
    Ice::Current& = Current())
    make: *** [servero] Error 1
    assoro: dacapo6>


    Line 30 in Sercer.cpp, which is reffered to is:

    std::ifstream file (path, ios::in|ios::binary);

    or

    ifstream file (path, ios::in|ios::binary);

    It makes no difference.

    Catalin
  • Looks as your fstream requires a const char* as first parameter? Try:

    ifstream file (path.c_str(), ios::in|ios::binary);

    If this works, complain to your STL vendor, as the STL you are using is not compliant with the C++ standard.

    Note that this problem has nothing do do with Ice.
  • Actually, I should have seen this earlier -- Marc is right, this has nothing to do with Ice, but you shouldn't complain to your compiler vendor either, because your compiler is right.

    The ISO standard defines the ifstream constructor as
    explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);
    

    Because the constructor is explicit, no user-defined conversions are applied to the constructor arguments, so, as Marc suggested, you must pass a const char* as the first argument.

    Cheers,

    Michi.
  • Originally posted by michi
    The ISO standard defines the ifstream constructor as
    explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in);
    
    Because the constructor is explicit, no user-defined conversions are applied to the constructor arguments, so, as Marc suggested, you must pass a const char* as the first argument.

    I agree with the resolution but not with the explanation: wether the constructor is defined explicit or not does not change the way conversions are applied to its arguments.
    The reason why the OP code did not work is that std::string has no (implicit) conversion operator to const char*.
    [I realize this is off-topic here, just wanted to add some clarification]

    Cheers,
    Bertrand.
  • Right you are -- I didn't look far enough. As you say, the real reason for the error is the absence of a conversion operator to const char* on std::string.
    Sorry for the confusion!

    Cheers,

    Michi.