6

I read here that C++17 is feature-complete although the specifications are not completely ready yet. How can I use C++17 features in my code, especially in Eclipse CDT (Neon)?

Specifically, I would like to use the filesystem to be able to iterate over directories easily.

cpplearner
  • 13,776
  • 2
  • 47
  • 72
chronosynclastic
  • 1,585
  • 3
  • 19
  • 40
  • Try passing `-std=c++1z` to your compiler? C++17 isn't finalized quite yet. `filesystem` will also depend on your choice of standard library and platform. – Yakk - Adam Nevraumont May 18 '17 at 12:38
  • Eclipse can't find `filesystem` when I pass `-std=c++1z`. I guess I have to find another way to iterate over directories. – chronosynclastic May 18 '17 at 13:19
  • Note that Eclipse CDT does not yet have IDE support for C++17 features, so while your code will compile, the IDE may show bogus syntax and semantics errors on code that uses some C++17 features, and some IDE features like navigation may not work properly on such code. – HighCommander4 May 18 '17 at 16:56
  • Also this answer should be useful (substitute `-stdc++17` for `-std=c++11`): https://stackoverflow.com/questions/17131744/eclipse-cdt-indexer-does-not-know-c11-containers/24628885#24628885 – Galik Dec 29 '17 at 02:04

2 Answers2

7

Both libc++ and libstdc++ have a std::experimental::filesystem in recent versions. I'm unaware of either having std::filesystem directly; C++17 isn't released quite yet, that seems reasonable.

boost has boost::filesystem, which differs in a few ways but is structured nearly identically. Code written to use boost::filesystem can be relatively easily ported to std::filesystem.

As an example of an incompatibility, boost has a singular flag enum, while std has a plural flag enum bitfield with more settings.

You may have to pass -std=c++1z to the compiler, check your libc++ or libstdc++ version, switch which one you are using, install a new one, etc. Or install boost, and use its filesystem library which C++17s was based off of.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • 2
    In addition, you need to explicitly link against the FS lib by passing `-lstdc++fs` (in case of libstdc++) or `-lc++experimental` (in case of libc++). This works for the latest gcc-7 package on the Ubuntu toolchain PPA as well as for the tip of trunk libc++. – TemplateRex May 28 '17 at 08:23
1

Although std::filesystem is scheduled to come with C++17, the current compiler implementations do not ship yet "official" C++17 support. As Yakk already stated in his answer, recent compiler and standard C++ library versions have std::experimental::filesystem.

At least for the GNU compiler g++ I can say that you do not even need to set the C++17 language dialect, using C++14 is sufficient! However, you need to link the (static) library libstdc++fs.a additionally.

Also, it is then quite convenient to define the std::filesystem namespace, so that you can use the headers (nearly) as if they were finalized already:

// ...

#include <experimental/filesystem>
namespace std {
    namespace filesystem = std::experimental::filesystem;
}

// now use std::filesystem ...

In summary:

  • Let eclipse use c++1y (C++14) dialect, this is sufficient
  • Link libstdc++fs.a
  • Include <experimental/filesystem>
King Thrushbeard
  • 869
  • 10
  • 16
  • 1
    I'd suggest doing `namespace fs = std::experimental::filesystem`, as populating the std namespace is not advised. There are a few valid cases to this, such as specializing templates with user-defined types, but declaring a namespace is not one. – Mário Feroldi Aug 11 '17 at 05:23
  • @MárioFeroldi Yes, you are right, thanks for your comment. I just intended my suggestion as "anticipating the upcoming standard" — never intended this as "final solution". Of course this must be removed in code latest, when C++17 is finally available. Also, your suggestion is the form that is promoted e.g. on http://en.cppreference.com/w/cpp/filesystem/path/path. – King Thrushbeard Aug 11 '17 at 09:54