user3489620
user3489620

Reputation: 65

Boost directory_iterator: 'begin' and 'end' not declared

I am trying to learn how to use the Boost C++ library, but I've run into a problem. When running the following boost::filesystem tutorial code:

#include <iostream>
#include <boost/filesystem.hpp>
using std::cout;
using namespace boost::filesystem;

int main(int argc, char* argv[])
{
    if (argc < 2)
    {
        cout << "Usage: tut3 path\n";
        return 1;
    }

    path p (argv[1]);

    try
    {
        if (exists(p))
        {
            if (is_regular_file(p))
                cout << p << " size is " << file_size(p) << '\n';

            else if (is_directory(p))
            {
                cout << p << " is a directory containing:\n";

                for (directory_entry& x : directory_iterator(p))
                    cout << "    " << x.path() << '\n'; 
            }
            else
                cout << p << " exists, but is not a regular file or directory\n";
        }
        else
            cout << p << " does not exist\n";
    }

    catch (const filesystem_error& ex)
    {
        cout << ex.what() << '\n';
    }

    return 0;
}

and compiling with:

g++ -std=c++11 main.cpp -o main -L$BOOST_ROOT -lboost_filesystem -lboost_system

or:

g++ -std=c++11 main.cpp -o main -L$BOOST_ROOT -lboost_system -lboost_filesystem

where BOOST_ROOT is the path where I extracted boost_1_62_0.tar.gz, I get the following error:

FoamData.cpp:36:76: error: ‘begin’ was not declared in this scope
          for (auto&& x : boost::filesystem::directory_iterator(p))
                                                                 ^
FoamData.cpp:36:76: note: suggested alternative:
In file included from /usr/include/c++/5/vector:66:0,
                 from FoamData.hpp:4,
                 from FoamData.cpp:1:
/usr/include/c++/5/bits/range_access.h:87:5: note:   ‘std::begin’
     begin(_Tp (&__arr)[_Nm])
     ^
FoamData.cpp:36:76: error: ‘end’ was not declared in this scope
          for (auto&& x : boost::filesystem::directory_iterator(p))
                                                                 ^
FoamData.cpp:36:76: note: suggested alternative:
In file included from /usr/include/c++/5/vector:66:0,
                 from FoamData.hpp:4,
                 from FoamData.cpp:1:
/usr/include/c++/5/bits/range_access.h:97:5: note:   ‘std::end’
     end(_Tp (&__arr)[_Nm])
     ^
make: *** [FoamData.o] Error 1

I apologize, in advance, if I have glossed over something obvious.

EDIT

The following statement from subsequent boost_filesystem tutorials gave the same error:

for(auto&& x : directory_iterator(p))

Code source: boost::filesystem tutorials

UPDATE

I recompiled boost_1_62_0 and ran the tutorial scripts to build the tutorial code (per the boost filesystem tutorial). The built tutorial programs work properly. However, when compiling using g++ outside of $BOOST_ROOT I am getting the following error:

./tester: error while loading shared libraries: libboost_system.so.1.62.0: cannot open shared object file: No such file or directory

Below is my makefile:

CC=g++
INCLUDE=-I/usr/local/boost_1_62_0
CFLAGS=-std=c++11 -Wall -Wextra -g
LDFLAGS=-lboost_filesystem -lboost_system
LDLIB=-L/usr/local/boost_1_62_0/stage/lib

all: tester

tester: main.o
    $(CC) main.o $(LDLIB) $(LDFLAGS) $(CFLAGS) -o tester

main.o: main.cpp
    $(CC) -c main.cpp $(INCLUDE) $(CFLAGS)

clean:
    rm *.o tester

FINAL UPDATE

I was able to eliminate the last of my errors by adding this to my .bashrc:

export LD_LIBRARY_PATH="$BOOST_ROOT/stage/lib:$LD_LIBRARY_PATH"

Thanks for all the help!

Upvotes: 1

Views: 3381

Answers (2)

oxygene
oxygene

Reputation: 631

Most probably your code is using the wrong (and outdated) system Boost libraries where the begin() and end() members are not provided in directory_iterator.

The reason is, that in your g++ command line you have provided an additional library path using -L, however you forgot to add an extra include path using -I.

You can add a compile time check for the boost version like this:

#include <boost/static_assert.hpp>
BOOST_STATIC_ASSERT(BOOST_VERSION >= 106200) // check for at least 1.62.0

Upvotes: 3

Baldrick
Baldrick

Reputation: 11860

Try using the following syntax instead:

   if (is_directory(p))
   {
      directory_iterator end_iter;

      for (directory_iterator dir_itr(p);
          dir_itr != end_iter;
          ++dir_itr)
      {
         std::cout << dir_itr->path().filename() << "\n";
      }
   }

This will list all the files in the directory.

The problem with your code is that you're not treating the object returned by directory_iterator(p) as an iterator.

The syntax you are using for the for loop expects a range expression, which should in this case be an object that has a begin and end method for getting at iterators. As you can see from the errors, the compiler is looking for these members.

Howerver, you've already created the begin iterator explictly - you're 'too late' to use the range syntax for the for loop.

Upvotes: 2

Related Questions