bork
bork

Reputation: 1674

C++ - no operator "<<" matches these operands directory_iterator()

I've copied the example code on the directory_iterator page, so this is what I have:

#include "pch.h" //for visual studios benefit
#include <fstream>
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;

int main()
{
    fs::create_directories("sandbox/a/b");
    std::ofstream("sandbox/file1.txt");
    std::ofstream("sandbox/file2.txt");
    for (auto& p : fs::directory_iterator("sandbox"))
        std::cout << p << '\n'; //this line on the first '<<' is where the error occurs
    fs::remove_all("sandbox");
    return 0; //included by me
}

And the error message is:

Severity    Code    Description Project File    Line    Suppression State
Error (active)  E0349   no operator "<<" matches these operands 

As I'm new to C++ I might have gotten things wrong, but my understanding of the error is basically that p in my case is something which can't be printed out to the console using cout.

The example works if I run it directly on the page so there isn't something wrong with it, which I wouldn't expect either. So question is, why am I seeing this error?

I use the latest version of Visual Studio, along with C++ 2017.

Upvotes: 3

Views: 627

Answers (4)

T.C.
T.C.

Reputation: 137315

directory_entry doesn't have streaming support directly; it gets it via path's operator<< plus an implicit conversion to const std::filesystem::path &.

As a result of LWG issues 2989 and 3065, path's operators have been made into hidden friends, and can no longer be used to stream things convertible to a path, such as a directory_entry.

The fix is to ask for .path() directly rather than depend on the implicit conversion. I've fixed the cppreference example.


After checking with LWG, this change appears to be unintended. I've filed LWG 3171.

Upvotes: 4

Peter
Peter

Reputation: 1611

Use the std::experimental namespace:

namespace fs = std::experimental::filesystem;

Upvotes: 2

gsamaras
gsamaras

Reputation: 73366

Change this:

namespace fs = std::filesystem;

to this:

namespace fs = std::experimental::filesystem;

because VS 17 uses an experimental version of the filesystem.

Upvotes: 2

Matthieu Brucher
Matthieu Brucher

Reputation: 22023

For Visual Studio 2017 (15.8 and 15.9 if I'm not mistaken), filesystem only exposes an experimental version, so use:

namespace fs = std::experimental::filesystem;

Upvotes: 1

Related Questions