Hi all,
I am an hobbyist programmer used to write programs for windows in a C style script (liteC). I am recycling myself so I learn to use C++. I am building a little project in VS2017 for WIN32 with an old D3D9 engine and ImGui. I have no problems to understand what classes, namespaces and scopes are.
I am building a file browser with std::experimental::filesystem and everything went right until, suddenly, the compiler stopped recognizing its namespace. VS recognizes it and it does not show any inclusion/namespace problem, but in compilation time it refuses to recognize the 'std' namespace, which was perfectly recognized yesterday evening.
I use a shortcut like the following for the filesystem module included into the class implementation file:
namespace fs = std::experimental::filesystem;
The error prompt:
Error C2653 'fs': is not a class or namespace name WMB7 Parser g:\visual studio\wmb7 parser\wmb7 parser\filebrowser.h 22
The error prompt when sustituting the namespace shortcut by the full namespace path:
Error C3083 'experimental': the symbol to the left of a '::' must be a type WMB7 Parser g:\visual studio\wmb7 parser\wmb7 parser\filebrowser.h 22
Error C3083 'filesystem': the symbol to the left of a '::' must be a type WMB7 Parser g:\visual studio\wmb7 parser\wmb7 parser\filebrowser.h 22
What could I have done to stop it from recognizing it? I am lost.
Thank you in advance.
Txes.
---------------------------------------------------------------------
UPDATE
Just noticed that everything works as expected when including the file system library into the main header instead of the class implementation file. Stunning...
---------------------------------------------------------------------
I am pretty sure that there are no systax errors in the source, but there you go anyway:
Main.h
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <d3d9.h>
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
#include <vector>
#include <string>
#include "imgui.h"
#include "imgui_impl_dx9.h"
#include "imgui_impl_win32.h"
#include "var.h"
#include "adll.h"
extern ENGINE_VARS *ev;
#define EBox(text) MessageBox(NULL, text, "CRITICAL_ERROR", 0);
FileBrowser.h
#pragma once
class FileBrowser {
public:
FileBrowser();
~FileBrowser();
bool Init();
void Close();
bool GetFolderContent(const char *_chrRoot, const char *_chrFolder);
bool Draw();
private:
char *m_drives[33];
char m_driveNames[99];
long m_driveCount;
long FindLogicalDrive(std::string _str);
fs::path m_pathRoot; fs::path m_pathFolder;
std::vector<std::string> m_path;
std::vector<std::string> m_content;
int m_current;
};
FileBrowser.cpp
#include "Main.h"
#include <experimental/filesystem>
#include "FileBrowser.h"
namespace fs = std::experimental::filesystem;
FileBrowser::FileBrowser() {
m_driveCount = 0;
m_path.reserve(16);
m_content.reserve(64);
m_current = -1;
}
FileBrowser::~FileBrowser() {
}
bool FileBrowser::Init() {
m_path.clear();
m_content.clear();
memset(m_drives, 0, sizeof(char*) * 33);
DWORD _logicalDrives = GetLogicalDrives();
m_driveCount = 0;
char *_chrT = m_driveNames;
for (char _l = 0; _l < 32; _l += 1) {
if (!(_logicalDrives & (1 << _l)))
continue;
m_drives[m_driveCount] = _chrT;
*_chrT = 65 + _l; *(_chrT + 1) = 58; *(_chrT + 2) = NULL;
_chrT += 3;
m_driveCount += 1;
}
GetFolderContent("", fs::current_path().u8string().c_str());
return true;
}
void FileBrowser::Close() {
m_path.clear();
m_content.clear();
}
bool FileBrowser::GetFolderContent(const char *_chrRoot, const char *_chrFolder) {
m_pathRoot = fs::u8path(_chrRoot);
m_pathFolder = fs::u8path(_chrFolder);
fs::path _pathFull;
if (*_chrRoot == NULL) {
_pathFull = m_pathFolder;
} else {
_pathFull = m_pathRoot;
_pathFull += "\\";
_pathFull += m_pathFolder;
}
if (!fs::exists(_pathFull))
return false;
if (!fs::is_directory(_pathFull))
return false;
size_t _folderCount = 0;
for (const fs::directory_entry& _p : fs::directory_iterator(_pathFull)) {
const fs::path& _path = _p.path();
DWORD _attb = GetFileAttributesW(_path.wstring().c_str());
if (_attb & FILE_ATTRIBUTE_HIDDEN)
continue;
if (_attb & FILE_ATTRIBUTE_SYSTEM)
continue;
if (fs::is_directory(_path)) {
m_content.insert(m_content.begin() + _folderCount, _path.filename().u8string().c_str());
_folderCount += 1;
} else {
m_content.push_back(_path.filename().u8string().c_str());
}
}
fs::path _pathFolder = m_pathFolder;
do {
const std::string _str = _pathFolder.filename().u8string().c_str();
if(_str.find("\\") == std::string::npos)
m_path.insert(m_path.begin(), _str);
_pathFolder = _pathFolder.parent_path();
} while (_pathFolder.has_filename());
return true;
}
long FileBrowser::FindLogicalDrive(std::string _str) {
for (long _i = 0; _i < m_driveCount; _i += 1) {
if (_str.find(m_drives[_i]) == std::string::npos)
continue;
return _i;
}
return -1;
}
bool PathContentGetter(void *_data, int _index, const char **_label) {
std::vector<std::string> *_content = (std::vector<std::string>*)_data;
*_label = (*_content)[_index].c_str();
return true;
}
bool FileBrowser::Draw() {
float _width = ImGui::GetContentRegionAvailWidth();
fs::path _pathFull = "";
for (unsigned long _i = 0; _i < m_path.size(); _i += 1) {
fs::path _path = fs::u8path(m_path[_i]);
if (_path.has_root_name()) {
long _drive = FindLogicalDrive(_path.u8string().c_str());
if (_drive < 0) {
EBox("Unknown error on logical drives search");
return false;
} else {
if (ImGui::BeginCombo("##DrivesCombo", m_drives[_drive], ImGuiComboFlags_NoArrowButton)) {
for (long _ii = 0; _ii < m_driveCount; _ii += 1) {
bool _isSelected = (_ii == _drive);
if (ImGui::Selectable(m_drives[_ii], &_isSelected, NULL)) {
EBox(m_drives[_ii]);
}
}
ImGui::EndCombo();
} else {
_pathFull = m_drives[_drive];
}
}
} else { if (_i != 0) {
_pathFull += "\\";
}
_pathFull += _path;
if (ImGui::Button(_path.u8string().c_str(), ImVec2(0, 0))) {
EBox(_pathFull.u8string().c_str());
}
}
}
ImGui::PushItemWidth(_width);
if (ImGui::ListBox("##PathContentList", &m_current, PathContentGetter, &m_content, m_content.size(), 6)) {
EBox(m_content[m_current].c_str());
}
return true;
}
What I have tried:
- Use the full namespace instead of the shortcut.
- Declare the namespace in the class header. Something I read I should not.
- Restore yesterdays code.
- Restart the system and the IDE.
- Modify file inclusion order.
- Not get desperated xP