我正在用C++做一个小的文件观察器,但是在一些重构之后,我遇到了一些问题。我主要了解问题出在哪里。我调用了一个实际上不是函数的函数,但我找不到这样的东西。所有的答案都说有一个名字,它被称为函数。
这是我的标题:
#ifndef FILEWATCHER_H
#define FILEWATCHER_H
#include <unordered_map>
#include <filesystem>
namespace fs = std::filesystem;
class FileWatcher
{
size_t currentNumberOfFiles = 0;
fs::path pathToWatch;
std::unordered_map<fs::path, fs::file_time_type> pathsMap;
std::string currentTime();
public:
FileWatcher(fs::path path);
void start();
};
#endif
和.cpp文件:
#pragma warning(disable : 4996)
#include "FileWatcher.h"
#include "Event.h"
std::string FileWatcher::currentTime()
{
auto now = std::chrono::system_clock::now();
std::time_t nowTime = std::chrono::system_clock::to_time_t(now);
std::string currentSystemTime = std::ctime(&nowTime);
return currentSystemTime;
}
FileWatcher::FileWatcher(fs::path pathToWatch)
{
this->pathToWatch = pathToWatch;
//create a map with last modification of a given file in the directory
for (auto& file : fs::directory_iterator(this->pathToWatch))
{
pathsMap.emplace(file.path(), fs::last_write_time(file));
}
}
void FileWatcher::start()
{
while (true)
{
currentNumberOfFiles = std::distance(fs::directory_iterator(pathToWatch), fs::directory_iterator());
for (std::unordered_map<fs::path, fs::file_time_type>::iterator it = pathsMap.begin(); it != pathsMap.end(); )
{
if (!fs::exists(it->first))
{
if (currentNumberOfFiles < pathsMap.size())
{
//std::cout << "File was erased" << std::endl;
it = pathsMap.erase(it);
//FileType fileType = ( ? FileType::FILE : FileType::DIRECTORY);
std::string time = this->currentTime();
Event event(EventType::DELETED, FileType::FILE, it->first, time);
event.printEvent();
}
else
{
//std::cout << "Renamed" << std::endl;
it = pathsMap.erase(it);
}
}
else
{
it++;
}
}
for (auto& file : fs::directory_iterator(pathToWatch))
{
if (!pathsMap.count(file.path()))
{
//std::cout << "File has been created" << std::endl;
pathsMap.emplace(file.path(), fs::last_write_time(file));
}
else
{
if (pathsMap.at(file.path()) != fs::last_write_time(file))
{
//std::cout << "File has been modified" << std::endl;
pathsMap.at(file.path()) = fs::last_write_time(file);
}
}
}
}
}
错误列表如下:
第一个错误:
Severity Code Description Project File Line Column Category Source Suppression State
Error C2056 illegal expression ProgrammingAssignment C:\VisualStudio2019\VC\Tools\MSVC\14.28.29910\include\xhash 130 44 Build
第二个错误:
Severity Code Description Project File Line Column Category Source Suppression State
Error C2064 term does not evaluate to a function taking 1 arguments ProgrammingAssignment C:\VisualStudio2019\VC\Tools\MSVC\14.28.29910\include\xhash 131 53 Build
这是filesystem
库中引用的位置错误列表。
template <class _Hasher, class _Kty>
_INLINE_VAR constexpr bool _Nothrow_hash = noexcept(
static_cast<size_t>(_STD declval<const _Hasher&>()(_STD declval<const _Kty&>())));
以下是错误输出:
Build started...
1>------ Build started: Project: ProgrammingAssignment, Configuration: Debug Win32 ------
1>FileWatcher.cpp
1>C:\VisualStudio2019\VC\Tools\MSVC\14.28.29910\include\xhash(131,53): error C2064: term does not evaluate to a function taking 1 arguments
1>C:\VisualStudio2019\VC\Tools\MSVC\14.28.29910\include\xhash(155): message : see reference to variable template 'const bool _Nothrow_hash<std::hash<std::filesystem::path>,std::filesystem::path>' being compiled
1>C:\VisualStudio2019\VC\Tools\MSVC\14.28.29910\include\xhash(155): message : while compiling class template member function 'size_t std::_Uhash_compare<_Kty,_Hasher,_Keyeq>::operator ()<_Kty>(const _Keyty &) noexcept(<expr>) const'
1> with
1> [
1> _Kty=std::filesystem::path,
1> _Hasher=std::hash<std::filesystem::path>,
1> _Keyeq=std::equal_to<std::filesystem::path>,
1> _Keyty=std::filesystem::path
1> ]
1>C:\VisualStudio2019\VC\Tools\MSVC\14.28.29910\include\xhash(1218): message : see reference to variable template 'const bool _Nothrow_hash<std::_Umap_traits<std::filesystem::path,std::chrono::time_point<std::filesystem::_File_time_clock,std::chrono::duration<__int64,std::ratio<1,10000000> > >,std::_Uhash_compare<std::filesystem::path,std::hash<std::filesystem::path>,std::equal_to<std::filesystem::path> >,std::allocator<std::pair<std::filesystem::path const ,std::chrono::time_point<std::filesystem::_File_time_clock,std::chrono::duration<__int64,std::ratio<1,10000000> > > > >,0>,std::filesystem::path>' being compiled
1>C:\VisualStudio2019\VC\Tools\MSVC\14.28.29910\include\xhash(1218): message : while compiling class template member function 'std::_List_iterator<std::_List_val<std::_List_simple_types<_Ty>>> std::_Hash<std::_Umap_traits<_Kty,std::chrono::time_point<std::filesystem::_File_time_clock,std::chrono::duration<std::chrono::system_clock::rep,std::chrono::system_clock::period>>,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>>::erase<std::_List_iterator<std::_List_val<std::_List_simple_types<_Ty>>>,0>(std::_List_iterator<std::_List_val<std::_List_simple_types<_Ty>>>) noexcept(<expr>)'
1> with
1> [
1> _Ty=std::pair<const std::filesystem::path,std::filesystem::file_time_type>,
1> _Kty=std::filesystem::path,
1> _Hasher=std::hash<std::filesystem::path>,
1> _Keyeq=std::equal_to<std::filesystem::path>,
1> _Alloc=std::allocator<std::pair<const std::filesystem::path,std::filesystem::file_time_type>>
1> ]
1>C:\VisualStudio2019\VC\Tools\MSVC\14.28.29910\include\xhash(130,44): error C2056: illegal expression
1>Done building project "ProgrammingAssignment.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
发布于 2021-03-12 09:05:13
错误消息很难阅读,但它基本上归结为缺少std::hash<std::filesystem::path>
的实现。
std::unordered_map
使用散列对其元素进行排序。默认情况下,它在地图的key_type
上使用std::hash
的专门化。但是,标准库没有为std::filesystem::path
提供std::hash
的专门化,因此出现了错误。
因此,如果您想使用std::filesystem::path
作为std::unordered_map
的key_type
,您必须执行以下任一操作:
std::hash<std::filesystem::path>
专业化认证,例如:template <>
class std::hash<fs::path>
{
public:
size_t operator()(const fs::path &path) const
{
return ... a hash of path ...;
}
};
class FileWatcher
{
...
std::unordered_map<fs::path, fs::file_time_type> pathsMap;
...
};
operator()
实现自定义的class
/struct
,该operator()
接受std::filesystem::path
作为输入,并返回唯一值作为输出。然后,您可以在std::unordered_map
的Hash
模板参数中显式声明该类型,例如:struct MyPathHash
{
size_t operator()(const fs::path &path) const
{
return ... a hash of path ...;
}
};
class FileWatcher
{
...
std::unordered_map<fs::path, fs::file_time_type, MyPathHash> pathsMap;
...
};
否则,请改用std::map
。它使用operator<
对元素进行排序,并且std::filesytem::path
实现了自己的operator<
,例如:
...
#include <map>
class FileWatcher
{
...
std::map<fs::path, fs::file_time_type> pathsMap;
...
};
https://stackoverflow.com/questions/66592585
复制相似问题